一、配置第三方库

查阅了网上的资料后,发现Java程序操作Excel表格的库中使用的比较多的是这个叫Apache POI API的库:

对应的maven依赖为:

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>

二、使用Apache POI API

1. 打开Excel文件

这一步相当于读取excel文件中的信息到对象中,方便我们进一步对数据进行操作(比较像Java程序中数据库映射的POJO对象)。当前我使用的文件是2007以上的,即后缀名为xlxs,此时创建对象的语句为:

Workbook book = new XSSFWorkbook("xxx.xlxs");

即在构造函数中填入对应的路径即可。当然,此外还有其他的构造函数,如下图所示:

但个人觉得最为常用的应该是填入路径File类型的对象了。

2. 选择对应的sheet

当我们使用Excel时可以发现左下角会有标注各个Sheet,即一个Excel文件像是一本书一样,里面有很多个表格,当我们需要操作一个表格时需要先切换到对应的表格页,如下图所示:

在程序中我们可以使用WorkBook的接口函数获取到一个表格页(即Sheet):

一共两种获取方式:

  1. 根据Sheet的名称获取:book.getSheet("Sheet1")
  2. 根据Sheet的索引获取:book.getSheetAt(0);

这两个方法的返回值都是Sheet接口类型。

3. Sheet接口的基本使用

3.1 获取开头行和结束行

在这个系统中,行号是从0开始数的,也就是说在程序中用到的行号是excel表格中显示的行号-1。

这里的测试表格采用数据库课程使用到的数据库表(即一个简单的员工数据表),如下图所示:

获取开头行和结束行:

// public interface Sheet
int getFirstRowNum();
int getLastRowNum();

示例程序:

@Test
public void t1() throws IOException {
Workbook book = new XSSFWorkbook("excel/test.xlsx");
Sheet table = book.getSheet("Sheet1");
System.out.println(table.getFirstRowNum());
System.out.println(table.getLastRowNum());
}

测试结果:

即开头行为第1行,在Java中为0,结束行为第18行,在Java程序中得到17。

3.2 获取Row对象

Row对象表示的是数据表中某一行的数据,可以通过以下方式获取一个Row对象:

// interface Sheet
Row getRow(int var1);

示例(获取包含所有第一行的数据的Row对象):

Row row = table.getRow(0);

4. Row对象的使用

4.1 获取本行的头尾索引

① 获取当前行第一个Cell对象的索引:row.getFirstCellNum()

tips: Cell对象为包含一个单元格所有信息的对象,这里即为获取本行第一个非空的单元格的下标

② 获取当前行最后一个Cell对象的索引+1:row.getLastCellNum()

注意这里并不是最后一个Cell对象的索引,而是该值+1(和前面的Sheet.getLastCellNum()有所不同),例如我们用程序打印出上面员工表第一行的firstCellNumlastCellNum

@Test
public void t1() throws IOException {
Workbook book = new XSSFWorkbook("excel/test.xlsx");
Sheet table = book.getSheet("Sheet1"); Row row = table.getRow(0);
System.out.println(row.getFirstCellNum());
System.out.println(row.getLastCellNum());
}

运行结果:

而员工表最后一列的索引为6,这说明了getLastCellNum()这个函数得到的是最后一个Cell的索引+1

对比sheet.getLastRowNum()row.getLastCellNum()也能发现不同之处(一个是获取索引,一个是获取索引+1):

// sheet.getLastRowNum()
public int getLastRowNum() {
return this._rows.isEmpty() ? -1 : (Integer)this._rows.lastKey();
} // row.getLastCellNum()
public short getLastCellNum() {
return (short)(this._cells.size() == 0 ? -1 : (Integer)this._cells.lastKey() + 1);
}

4.2 获取Cell对象

一行中有多个Cell对象(即单元格对象),我们可以通过row.getCell(int index)获取Cell对象,例如我们这里循环获取第2行的每一个Cell对象,并且将它们分别打印出来:

Row row = table.getRow(1);
for (int i = 0; i < row.getLastCellNum(); i++) {
Cell cell = row.getCell(i);
System.out.println(cell);
}

Excel第2行:

运行结果:

此外,我们还可以通过迭代器的方式获取该行的每个Cell对象,获取迭代器的的方法为row.cellIterator(),最后将它们打印出来:

Row row = table.getRow(1);
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
System.out.println(cell);
}

运行结果与上同。

阅读源码后发现在JDK1.8之后,当一个对象实现了Iterable接口之后,就已经实现了forEach方法,因此我们也可以使用这个方法来遍历Row对象中的Cell

Row row = table.getRow(1);
row.forEach(cell -> {
System.out.print(cell+", ");
System.out.println(cell.getCellType());
});

同理,Sheet对象也可以使用forEach进行遍历。

5. Cell对象的使用

5.1 获取单元格值的类型

使用方法:

// public interface Cell
CellType getCellType();

返回类型为CellType,它是一个枚举类型,源码如下:

public enum CellType {
_NONE(-1),
NUMERIC(0),
STRING(1),
FORMULA(2),
BLANK(3),
BOOLEAN(4),
ERROR(5);
}

一般Excel中填写的内容对应的类型:

  1. 没有填值(空单元格):BLANK
  2. 数字(整数或小数):NUMERIC
  3. 字符串:STRING
  4. 公式:FORMULA
  5. TRUE或FALSE:BOOLEAN

准备如下的测试行:

执行以下代码(即将上面这行单元格的值和类型都打印出来):

Row row = table.getRow(18);
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
System.out.print(cell+", ");
System.out.println(cell.getCellType());
}

运行结果:

5.2 获取单元格的值

方法:cell.getXXXValue()

例如如果这个单元格是数字类型的,就使用getNumericCellValue()即可

需求,获取所有SALESMAN员工的工资和:

5.3 设置单元格的值

和前面获取值类似地,可以使用:cell.setValue(Object value)的方法设置单元格的值:

但需要注意的是,这里仅是对存在于内存中的对象进行属性的设置,并不会直接影响到Excel表格中实际的内容,如果需要用book对象来修改表格内容则还需要使用保存功能来执行。(和POJO是类似的,需要先修改对象的值,然后再用整个对象去修改数据库中实际的值)

6. 保存表格

步骤如下:

  1. 新建一个FileOutputStream对象,相当于是一个文件,如果是已存在的文件则进行覆盖操作
  2. 使用Workbook对象的void write(OutputStream var1)方法,填入的参数为前面的FileOutputStream对象

这样表格就保存完成了。

示例:

@Test
public void t() throws IOException {
Workbook book = new XSSFWorkbook();
Sheet table = book.createSheet();
Row row = table.createRow(0);
Cell firstCell = row.createCell(0);
firstCell.setCellValue("Hello");
Cell secondCell = row.createCell(1);
secondCell.setCellValue("World");
FileOutputStream fos = new FileOutputStream("excel/output.xlsx");
book.write(fos);
book.close();
}

运行效果:

如果希望修改原表格只需在fos的路径上填原表格就可以进行覆盖了

使用Java操作Excel表格的更多相关文章

  1. Java操作excel表格

    (1)Java读取excel表格 package com.songyan.excel; import java.io.File; import java.io.FileInputStream; imp ...

  2. java 操作Excel表格

    对于Excel表格的解析.生成,java在 org.apache.poi 包中已经封装好了,使用比较简单. 解析Excel: 首先将File文件转成InputStream InputStream in ...

  3. Java——操作Excel表格,读取表格内容

    JAVA EXCEL API:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过 ...

  4. jxl的使用总结(java操作excel)

    jxl.jar是通过java操作excel表格的工具类库: jxl.jar包:链接:http://pan.baidu.com/s/1o8qFJHw 密码:5jyq 1:通过模拟实现创建一个表格,然后模 ...

  5. 【转载】jxl的使用总结(java操作excel)

    jxl.jar是通过java操作excel表格的工具类库: 链接:https://pan.baidu.com/s/1AAT_eA_Q47zFeQohap6eQg 提取码:777b 1:通过模拟实现创建 ...

  6. Java 操作 EXCEL

    今天帮朋友写了一段用来处理EXCEL内容的程序,在这里记录下自己的学习过程.主要是对EXCEL表格中的内容做分类和统计,使用计算机来做这种重复的机械性地工作再好不过了.首先,我们需要下载一个java操 ...

  7. JAVA操作Excel时文字自适应单元格的宽度设置方法

    使用JAVA操作Excel通常都使用JXL,方法很简单网上也有很多的教程,然后往往一些细节性的问题却导致我们这些Programmer苦恼不已.这两天帮一个朋友做一个Excel表格自动生成的小软件,就遇 ...

  8. java操作excel 工具类

    java操作excel 可参考https://blog.csdn.net/xunwei0303/article/details/53213130 直接上代码: 一.java生成excel文件: pac ...

  9. java实现excel表格导入数据库表

    导入excel就是一个上传excel文件,然后获取excel文件数据,然后处理数据并插入到数据库的过程 一.上传excel 前端jsp页面,我的是index.jsp 在页面中我自己加入了一个下载上传文 ...

随机推荐

  1. JVM学习笔记-第七章-虚拟机类加载机制

    JVM学习笔记-第七章-虚拟机类加载机制 7.1 概述 Java虚拟机描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被 ...

  2. golang 日志框架(zap)完整配置和使用

    目录结构: logger.go文件: package log import ( rotatelogs "github.com/lestrrat-go/file-rotatelogs" ...

  3. vim编辑文件时[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:

    ​​ ​ ​ 出现这个问题是因为你上次编辑的时候在没有保存的情况下退出了(如:电脑关机等)也有可能是有其他人在和你同时进行编辑行为(不同会话中).这是因为在用vim编辑的时候,vim会在打开文件目录下 ...

  4. Python成员运算,身份运算和流程控制

    成员运算 in #判断--在--里面 print('a' in 'abcd') # 字符串判断a是否在abcd里面 print('you' in 'how are you') # 这种整体也可以判断 ...

  5. .Net Core with 微服务 - 分布式事务 - TCC

    上一次我们讲解了分布式事务的 2PC.3PC .那么这次我们来理一下 TCC 事务.本次还是讲解 TCC 的原理跟 .NET 其实没有关系. TCC Try 准备阶段,尝试执行业务 Confirm 完 ...

  6. 教你使用ApiPost中的全局参数和目录参数

    前面的示例中,我们都是在单一接口中填入不同的请求header.query.body参数.但在实际项目中,对于一批接口,往往具有相同的请求参数.此时,我们可以利用全局参数或者目录参数实现. 例如:常见的 ...

  7. 队列(Queue)\双端队列(Deque)

    队列(Queue)\双端队列(Deque) 队列(Queue) 双端队列(Deque) 算法应用 队列(Queue) 特点: 和栈不同,队列的最大特点是先进先出(FIFO),就好像按顺序排队一样.对于 ...

  8. Int 2e 与 Sysenter区别

    参考:张银奎<软件调试>第八章 Int 2e: Windows将2e号向量专门用作系统调用,在启动早起初始化中断描述表时便注册好了适合的服务例程.因此当NtDll中的NtReadFile发 ...

  9. 默认标签的解析过程(三)parseDefaultElement

    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate. ...

  10. 解决Openstack Dashboard无法获取实例故障

    在部署配置完openstack基础服务以及dashboard后.登录页面发现很多功能都不正常,无法获取实例,也无法获取镜像. 查看日志 [root@openstack-controller-dev ~ ...