easyexcel流式导出
EasyExcel 支持流式导出,这是它的一个重要特性。流式导出可以有效解决大数据量导出时的内存溢出问题。
流式导出的优势
- 内存友好 :不会一次性将所有数据加载到内存中
- 适合大数据量 :可以处理百万级甚至更多的数据
- 性能稳定 :内存占用相对固定,不会随数据量增长而线性增加
基本用法示例
1. 简单流式导出
@GetMapping("/export")
public void export(HttpServletResponse response) throws IOException {// 设置响应头response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=data.xlsx");// 创建ExcelWriter对象ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), DemoData.class).build();// 分页查询数据并写入int pageSize = 1000;int pageNum = 1;while (true) {List<DemoData> dataList = getDataFromDatabase(pageNum, pageSize);if (dataList.isEmpty()) {break;}// 写入当前页数据WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();excelWriter.write(dataList, writeSheet);pageNum++;}// 关闭流excelWriter.finish();
}
2. 使用分页助手
@GetMapping("/exportWithPage")
public void exportWithPage(HttpServletResponse response) throws IOException {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=data.xlsx");EasyExcel.write(response.getOutputStream(), DemoData.class).sheet("Sheet1").doWrite(() -> {// 分页查询数据List<DemoData> dataList = new ArrayList<>();int pageSize = 1000;int pageNum = 1;while (true) {List<DemoData> pageData = getDataFromDatabase(pageNum, pageSize);if (pageData.isEmpty()) {break;}dataList.addAll(pageData);pageNum++;}return dataList;});
}
3. 手动控制写入过程
@GetMapping("/exportManual")
public void exportManual(HttpServletResponse response) throws IOException {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=data.xlsx");ExcelWriter excelWriter = null;try {excelWriter = EasyExcel.write(response.getOutputStream(), DemoData.class).build();WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();// 分批写入数据int pageSize = 1000;int pageNum = 1;while (true) {List<DemoData> dataList = getDataFromDatabase(pageNum, pageSize);if (dataList.isEmpty()) {break;}excelWriter.write(dataList, writeSheet);pageNum++;}} finally {if (excelWriter != null) {excelWriter.finish();}}
}
4. 多Sheet流式导出
@GetMapping("/exportMultiSheet")
public void exportMultiSheet(HttpServletResponse response) throws IOException {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=data.xlsx");ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), DemoData.class).build();try {// 第一个SheetWriteSheet sheet1 = EasyExcel.writerSheet(0, "Sheet1").build();List<DemoData> data1 = getDataForSheet1();excelWriter.write(data1, sheet1);// 第二个SheetWriteSheet sheet2 = EasyExcel.writerSheet(1, "Sheet2").build();List<DemoData> data2 = getDataForSheet2();excelWriter.write(data2, sheet2);} finally {excelWriter.finish();}
}
注意事项
- 及时关闭资源 :使用完后要调用
excelWriter.finish()
关闭流 - 异常处理 :要做好异常处理,确保资源能够正确释放
- 数据分页 :合理设置分页大小,一般建议1000-5000条数据为一批
- 内存监控 :虽然流式导出内存友好,但仍需监控JVM内存使用情况
流式导出是EasyExcel处理大数据量导出的最佳实践,特别适合需要导出大量数据的业务场景。