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處理大數據量導出的最佳實踐,特別適合需要導出大量數據的業務場景。