一、Apache POI简介
Apache POI 是一个开源的 Java 库,用于读取和写入各种 Microsoft Office 格式的文件,允许开发者在 Java 应用程序中操作这些文件,而无需依赖 Microsoft Office 软件。一般情况下POI都是用来操作Excel文件的。
使用场景
-
数据导出:将数据导出为 Excel 或 Word 格式,方便用户下载和查看。
-
数据导入:批量导入业务数据。
-
报表生成:生成复杂的报表,支持图表和格式化。
-
自动化测试:读取测试数据或生成测试报告。
二、入门案例
1、maven依赖导入
<!-- poi 为核心模块,支持旧版 Microsoft Office 文件格式(基于二进制格式)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<!-- poi-ooxml 为扩展,支持 新版 Microsoft Office 文件格式(基于 XML 格式) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
2.基本读写操作演示
写操作及结果
向excel中写入数据,POI中的对象名和方法名基本上见名知意,操作步骤和手动创建也大同小异,这里大家跟着注释自行查看,不过多赘述
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
/**
* 使用poi操作Excel文件
*/
public class POITest {
/**
* 通过POI创建Excel文件并写入文件内容
*/
public static void write() throws Exception {
//在内存中新建一个Excel文件
XSSFWorkbook excel = new XSSFWorkbook();
//在excel新建一个sheet页
XSSFSheet sheet = excel.createSheet("info");
//在sheet中创建行对象
XSSFRow row = sheet.createRow(1);//行号从零开始,这里表示第二行
row.createCell(0).setCellValue("姓名");//单元格也从零开始
row.createCell(1).setCellValue("年龄");
//创建新行
row = sheet.createRow(2);//行号从零开始
row.createCell(0).setCellValue("cds");//单元格也从零开始
row.createCell(1).setCellValue("20");
row = sheet.createRow(3);//行号从零开始
row.createCell(0).setCellValue("ccc");//单元格也从零开始
row.createCell(1).setCellValue("50");
//通过输出流将内存中的Excel文件写入磁盘
FileOutputStream outputStream = new FileOutputStream("D:\\info.xlsx");
excel.write(outputStream);
//关闭资源
outputStream.close();
excel.close();
}
public static void main(String[] args) throws Exception {
write();
}
}
读操作及结果
读操作中有一点需要注意getLastCellNum()返回的是该行中最后一个已使用的单元格的索引+1,所以我们在循环时没有取=。除此之外不论是行或单元格的getLas/First方法,都不对null做计数,即忽略未使用单元格。
public static void read() throws IOException {
FileInputStream inputStream = new FileInputStream(new File("D:\\info.xlsx"));
//读取磁盘上已存在的Excel文件
XSSFWorkbook excel = new XSSFWorkbook(inputStream);
//读取第一个sheet页
XSSFSheet sheet = excel.getSheetAt(0);
//获取最后一行索引: 行号减一
int lastRowNum = sheet.getLastRowNum();
//获取第一行索引: 行号减一
int firstRowNum = sheet.getFirstRowNum();
for (int i = firstRowNum; i <= lastRowNum; i++) {
//获取第i行
XSSFRow row = sheet.getRow(i);
//获取单元格对象
short firstCellNum = row.getFirstCellNum();
//返回的是该行中最后一个已使用的单元格的索引加一
short lastCellNum = row.getLastCellNum();
for (int j = firstCellNum; j <lastCellNum ; j++) {
String cellValue = row.getCell(j).getStringCellValue();
System.out.print(cellValue+"\t");
}
System.out.println();
}
inputStream.close();
excel.close();
我们简单修改一下写操作的结果表,再分析一下读操作的结果
firstRowNum:1 第一行索引为1,行号为2
第五行lastCellNum:2 最后一个已使用的单元格的索引为1
第六行lastCellNum:1 最后一个已使用的单元格的索引为0,不会识别后面的null
lastRowNum:7 最后一行索引为7,行号为8
由于索引6行号7单元格都为null所以遍历到此处会报错
三、实际应用
POI的操作虽然相对清析,但这样一行行一个个的操作方式依然相当繁琐,其实在实际应用中并不要求我们操作每一个单元格来完成表单,以Spring Boot项目中输出业务报表为例,我们往往会先写好表格的大部分样式内容template,只需要查询填充关键数据即可。
场景描述:
项目前端浏览器页面有导出数据按钮,点击即可生成excel报表并下载。
下面是事先准备好的表格样式,大家可以先自行判断需要填入位置的具体操作
数据填入:
接下来我用本地的项目和数据库演示一下数据填入操作,VO对象包含了所有所需信息,具体查询直接略过,大家根据注释熟悉场景和读写操作即可
/**
* 导出运营数据报表
* @param response
*/
public void exportStatistics(HttpServletResponse response) {
//查询数据库
BusinessDataVO businessData = workspaceService.getBusinessData(30);
//POI写入Excel
//读取模板
InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
try {
//基于模板文件创建新excel
XSSFWorkbook excel = new XSSFWorkbook(in);
//获取sheet1表
XSSFSheet sheet = excel.getSheet("sheet1");
//填充数据---时间
sheet.getRow(1).getCell(1).setCellValue("时间:"
+LocalDate.now().minusDays(30)+"至"+LocalDate.now());
//获取第四行
XSSFRow row = sheet.getRow(3);
row.getCell(2).setCellValue(businessData.getTurnover());
row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
row.getCell(6).setCellValue(businessData.getNewUsers());
//获取第五行
row=sheet.getRow(4);
row.getCell(2).setCellValue(businessData.getValidOrderCount());
row.getCell(4).setCellValue(businessData.getUnitPrice());
//通过输出流将excel文件下载到客户端浏览器
ServletOutputStream out = response.getOutputStream();
excel.write(out);
//关闭资源
out.flush();
out.close();
excel.close();
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
结果演示:
POI的基本使用就讲解到这里,大家可以自行尝试,本片分享到此结束。