二十二、Apache POI
Apache POI是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用POI在Java
序中对Miscrosoft Office各种文件进行读写操作。一般情况下,POI都是用于操作Excel文件。
使用场景:银行网银系统导出交易明细、各种业务系统导出Excel报表、批量导,入业务数据。
1、入门案例
-
导入对应的Maven坐标
xml<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</version> </dependency> <dependency> <groupId>org.apache .poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.16</version> </dependency>
-
创建Excel工作簿,并对其写入和读取
javapublic class POITest { /** 通过POI.创建Excel.文件并且写入文件内容 */ public static void wirteExcel() throws Exception{ // 在内存中创建一个EXcel工作簿 XSSFWorkbook workbook = new XSSFWorkbook(); // 在工作簿中创建一个工作表,并命名为info XSSFSheet sheet = workbook.createSheet("info"); // 在info工作表中创建一行,行号是从0开始的 XSSFRow row = sheet.createRow(1); // 在row行中创建一个单元格,列号从0开始,并设置单元格的值为,姓名(2行3列)性别(2行4列) row.createCell(2).setCellValue("姓名"); row.createCell(3).setCellValue("性别"); //再次创创建一个新行,第3行 row=sheet.createRow(2); // 在row行中创建单元格,并设置单元格的值 row.createCell(2).setCellValue("张三"); row.createCell(3).setCellValue("男"); // 再次创建一个新行,第4行 row=sheet.createRow(3); row.createCell(2).setCellValue("小明"); row.createCell(3).setCellValue("女"); // 将内存中的数据写入到磁盘中 OutputStream outputStream=new FileOutputStream("D:\\info.xlsx"); workbook.write(outputStream); // 写入到输出流中 //关闭资源 outputStream.close(); workbook.close(); } /** * 读取Excel文件 * @throws Exception */ public static void readExcel() throws Exception{ // 创建输入流对象 InputStream inputStream=new FileInputStream("D:\\info.xlsx"); //从输入流中读取一个工作簿 XSSFWorkbook workbook=new XSSFWorkbook(inputStream); // 根据名字来获取工作表 // XSSFSheet sheet = workbook.getSheet("info"); //根据下标来获取工作表 XSSFSheet sheet = workbook.getSheetAt(0); // 获取最后一行的行号(下标从0开始的) Integer lastRowNum = sheet.getLastRowNum(); // 循环读取每一行,以及每一行对应的单元格数据,(第一行为空白,我们从第二行开始读取,下标为1) for(int i=1;i<=lastRowNum;i++){ XSSFRow row = sheet.getRow(i); // 获取第i行 String name = row.getCell(2).getStringCellValue(); // 获取第i行,第3列的数据 String sex = row.getCell(3).getStringCellValue(); // 获取第i行,第4列的数据 System.out.println(name+"---"+sex); } // 关闭资源 inputStream.close(); workbook.close(); } public static void main(String[] args) throws Exception { wirteExcel(); readExcel(); } }
2、实操案例
报表导出,营业数据导出到工作表中,下载下来。
接口:没有参数,也没有返回值。
一般情况下,想这个比较复杂的工作表,都是不需要提供POI来创建的,一般是手动创建这样一个模板文件,通过输入流将其读取进去,只需要将数据写入对应的单元格,通过输出流由客户端、浏览器进行下载即可。
2.1 Controller层
java
/**
* 导出运营数据报表
*/
@Operation(summary = "导出运营数据报表")
@GetMapping("/export")
public void getBusinessReportData(HttpServletResponse response){
// 调用service导出报表,传入响应对象
reportService.exportBusinessReport(response);
}
2.2 Service层
java
/**
* 导出运营数据报表
* @param response
*/
@Override
public void exportBusinessReport(HttpServletResponse response) {
//1、获取运营数据
LocalDate beginDate=LocalDate.now().minusDays(30);
LocalDate endDate=LocalDate.now().minusDays(1);
LocalDateTime beginTime=LocalDateTime.of(beginDate,LocalTime.MIN);
LocalDateTime endTime=LocalDateTime.of(endDate,LocalTime.MAX);
BusinessDataVO businessDataVO= workspaceService.getBusinessData(beginTime,endTime); //获取运营数据
//2、将数据写入到模板文件中
//2.1、获取模板文件
log.info("name:{}",this.getClass().getClassLoader());
//通过类加载器,获取到路径:src/main/resources,再拼接路径:template/运营数据报表模板.xlsx
InputStream inputStream=this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
try {
//2.2、通过模块创建工作簿
XSSFWorkbook workbook=new XSSFWorkbook(inputStream);
//2.3、读取第一个工作表
XSSFSheet sheet=workbook.getSheetAt(0);
//2.4、设置时间数据
sheet.getRow(1).getCell(0).setCellValue("日期范围:"+beginDate+" 至 "+endDate);
//2.5、设置概况数据
XSSFRow row= sheet.getRow(3);
row.getCell(1).setCellValue(businessDataVO.getTurnover().doubleValue());//营业额
row.getCell(3).setCellValue(businessDataVO.getOrderCompletionRate()); //订单完成率
row.getCell(5).setCellValue(businessDataVO.getNewUsers()); //新增用户数
row= sheet.getRow(4);
row.getCell(1).setCellValue(businessDataVO.getValidOrderCount());//有效订单数
row.getCell(3).setCellValue(businessDataVO.getUnitPrice().doubleValue());//平均客单价
//2.6、设置订单明细数据
for(int i=0;i<30;i++){
LocalDate date=beginDate.plusDays(i);
LocalDateTime begin=LocalDateTime.of(date,LocalTime.MIN);
LocalDateTime end=LocalDateTime.of(date,LocalTime.MAX);
businessDataVO=workspaceService.getBusinessData(begin,end);
row= sheet.getRow(7+i);
row.getCell(0).setCellValue(date.toString()); //日期
row.getCell(1).setCellValue(businessDataVO.getTurnover().doubleValue()); //营业额
row.getCell(2).setCellValue(businessDataVO.getValidOrderCount()); //有效订单数
row.getCell(3).setCellValue(businessDataVO.getOrderCompletionRate());//订单完成率
row.getCell(4).setCellValue(businessDataVO.getUnitPrice().doubleValue());
row.getCell(5).setCellValue(businessDataVO.getNewUsers()); //新增用户数
}
//3、将文件输出到浏览器 浏览器下载
ServletOutputStream servletOutputStream = response.getOutputStream();
workbook.write(servletOutputStream);
//4、关闭资源
workbook.close();
servletOutputStream.close();
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
}