百萬級Excel匯出方案
阿新 • • 發佈:2021-02-06
百萬資料量excel匯出方案
- 編寫目的
在實際場景中excel報表匯出業務比較常見,隨著業務量及資料量遞增,報表匯出資料量大的情況下容易出現記憶體溢位,響應耗時太長等問題,現提供百萬資料量內的報表匯出方案,供大家參考。
- 適用範圍
Java開發工程師
- 方案說明
- 問題說明
- 大批量資料匯出容易瞬間打滿老年代導致Full GC頻繁發生,容易系統卡死。
- 一次性把目標資料全部查詢出來再寫到流中的方式,大量被查詢的物件駐留在堆記憶體中,直接打滿整個堆,容易堆記憶體溢位。
- 核心思路
- 底層使用POI Excel SXSSF,Excel 2007一個頁籤只能放1048576行資料、16384列。這裡用alibba開源EsayExcel。
- 資料批量分頁查出,輸出到流。如果有自增主鍵,可採用滾動分頁方式,查詢效率優化比較明顯。
SELECT * FROM tableX WHERE id > #{lastBatchMaxId} [其他條件] ORDER BY id [ASC|DESC](這裡一般選用ASC排序) LIMIT ${size}
- 參考程式碼
Pom引入easyexcel
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.1.4</version> </dependency>
參考程式碼@
@GetMapping(path = "/exportId") public void exportId(@RequestParam("pageSize") int pageSize, @RequestParam("pageNum") int pageNum, HttpServletResponse response) throws Exception { long startTime = System.currentTimeMillis(); ExcelWriter writer = null; try { String fileName = URLEncoder.encode(String.format("%s-(%s).csv", "訂單支付資料", UUID.randomUUID().toString()), StandardCharsets.UTF_8.toString()); response.setContentType("application/force-download"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); writer = new ExcelWriterBuilder() .autoCloseStream(true) .excelType(ExcelTypeEnum.XLSX) .file(response.getOutputStream()) .head(OrderRecordExportDO.class) //註冊自定義時間格式轉換,easyExceL目前支援Date,不支援LocalDateTime,需要自定義時間轉換器 .registerConverter(new LocalDateTimeConverter()) .build(); // xlsx檔案上上限是104W行左右,這裡如果超過104W需要分Sheet WriteSheet writeSheet = new WriteSheet(); writeSheet.setSheetName("target"); long lastBatchMaxId = 0L; //2、查詢原資料表交易 for (int i = 1; i <= pageNum; i++) { long startSelect=System.currentTimeMillis(); log.debug("i=[{}]", i); List<OrderRecordExportDO> orders = orderRecordMapper.exportLimitId(lastBatchMaxId,pageSize); log.info("[源資料交易數][{}][{}],耗時={}", i, orders.size(),System.currentTimeMillis()-startSelect); lastBatchMaxId = orders.stream().map(OrderRecordExportDO::getId).max(Long::compareTo).orElse(Long.MAX_VALUE);
G測試情況
總數=800000,pageSize=10000,pageNum=80,耗時=48046ms10列 130M
表格樣式,模板檔案匯出可以檢視esayExcel官網。
https://www.yuque.com/easyexcel/doc/easyexcel
參考地址
https://www.cnblogs.com/throwable/p/13285518.html