/**
* 导出运营数据报表
* @param response HttpServletResponse 对象,用于将生成的 Excel 文件发送到客户端
*/
public void exportBusinessData(HttpServletResponse response) {
// 定义开始和结束日期:从今天开始的前30天到昨天
LocalDate dateBegin = LocalDate.now().minusDays(30);
LocalDate dateEnd = LocalDate.now().minusDays(1);
// 1. 查询数据库获取营业数据
// 调用服务获取指定日期范围内的业务数据
BusinessDataVO businessDataVO = workspaceService.getBusinessData(LocalDateTime.of(dateBegin, LocalTime.MIN), LocalDateTime.of(dateEnd, LocalTime.MAX));
// 2. 通过 Apache POI 将数据写入到 Excel 文件
// 获取模板文件的输入流
InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板");
try {
// 基于模板文件创建新的 Excel 工作簿
XSSFWorkbook excel = new XSSFWorkbook(in);
// 获取工作簿中的第一个工作表
XSSFSheet sheet = excel.getSheet("Sheet1");
// 填充数据时间
// 在模板中的特定单元格中设置日期范围
sheet.getRow(1).getCell(1).setCellValue("时间:" + dateBegin + "至" + dateEnd);
// 填充汇总数据
// 获取模板中的第4行并填充相应的业务数据
XSSFRow row = sheet.getRow(3);
row.getCell(2).setCellValue(businessDataVO.getTurnover());
row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
row.getCell(6).setCellValue(businessDataVO.getNewUsers());
row = sheet.getRow(4);
row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
row.getCell(4).setCellValue(businessDataVO.getUnitPrice());
// 填充每日明细数据
// 遍历过去30天的每一天,获取每天的业务数据并填充到相应的行中
for (int i = 0; i < 30; i++) {
LocalDate date = dateBegin.plusDays(i);
BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
row = sheet.getRow(7 + i);
row.getCell(1).setCellValue(date.toString());
row.getCell(2).setCellValue(businessData.getTurnover());
row.getCell(3).setCellValue(businessData.getValidOrderCount());
row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
row.getCell(5).setCellValue(businessData.getUnitPrice());
row.getCell(6).setCellValue(businessData.getNewUsers());
}
// 3. 通过输出流将 Excel 文件下载到客户端浏览器
ServletOutputStream out = response.getOutputStream();
excel.write(out); // 将工作簿写入输出流
// 关闭资源
out.close();
excel.close();
} catch (IOException e) {
e.printStackTrace(); // 捕获并打印 IO 异常
}
}
代码解析
-
日期计算:
LocalDate dateBegin = LocalDate.now().minusDays(30);
:计算30天前的日期。LocalDate dateEnd = LocalDate.now().minusDays(1);
:计算昨天的日期。
-
查询业务数据:
workspaceService.getBusinessData(LocalDateTime.of(dateBegin, LocalTime.MIN), LocalDateTime.of(dateEnd, LocalTime.MAX));
:调用服务方法,获取指定日期范围内的业务数据。
-
读取Excel模板:
InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板");
:读取存储在资源目录中的Excel模板文件。
-
创建和填充Excel文件:
XSSFWorkbook excel = new XSSFWorkbook(in);
:基于模板创建新的Excel工作簿。XSSFSheet sheet = excel.getSheet("Sheet1");
:获取工作簿中的第一个工作表。- 使用各种
setCellValue
方法将业务数据填充到指定单元格中。
-
填充每日明细数据:
- 使用循环遍历过去的30天,每天调用一次
workspaceService.getBusinessData
方法,获取当天的业务数据并填充到Excel的相应行中。
- 使用循环遍历过去的30天,每天调用一次
-
输出Excel文件:
ServletOutputStream out = response.getOutputStream();
:获取HTTP响应的输出流。excel.write(out);
:将生成的Excel工作簿写入输出流。- 关闭输出流和工作簿,释放资源。
-
异常处理:
- 捕获并打印IO异常,确保在异常情况下也能进行适当的日志记录。