各人好,我是 V 哥。使用EasyExcel举行大数据量导出时轻易导致内存溢出,特别是在导出百万级别的数据时。你有碰到过这种情况吗,以下是V 哥整理的解决该问题的一些常见方法,分享给各人,接待一起讨论:
EasyExcel大数据量导出常见方法
1. 分批写入
- EasyExcel支持分批写入数据,可以将数据分批加载到内存中,分批写入Excel文件,避免一次性将大量数据加载到内存中。
- 示例代码:
- String fileName = "large_data.xlsx";
- ExcelWriter excelWriter = EasyExcel.write(fileName).build();
- WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
- // 假设每次写入10000条数据
- int batchSize = 10000;
- List<Data> dataList;
- int pageIndex = 0;
- do {
- // 分页获取数据
- dataList = getDataByPage(pageIndex++, batchSize);
- excelWriter.write(dataList, writeSheet);
- } while (dataList.size() == batchSize);
- // 关闭资源
- excelWriter.finish();
复制代码 2. 设置合适的JVM内存
- 针对大数据导出场景,可以实行增大JVM的内存分配,例如:
- java -Xms512M -Xmx4G -jar yourApp.jar
复制代码
- 解释:
- -Xms512M:设置初始堆大小为512MB。
- -Xmx4G:设置最大堆大小为4GB。
3. 淘汰数据对象的复杂性
- 导出数据时,尽量简化数据对象,避免不必要的嵌套和多余字段的加载,以淘汰对象占用的内存空间。
4. 关闭自动列宽设置
- EasyExcel的自动列宽功能会占用大量内存,特别是在数据量较大的情况下。关闭自动列宽可以节省内存。
- 示例代码:
- EasyExcel.write(fileName)
- .registerWriteHandler(new SimpleWriteHandler()) // 不使用自动列宽
- .sheet("Sheet1")
- .doWrite(dataList);
复制代码 5. 使用Stream导出(适合大数据)
- 利用OutputStream分批写入数据,淘汰内存斲丧。通过BufferedOutputStream可以进一步提高性能。
- 示例代码:
- try (OutputStream out = new BufferedOutputStream(new FileOutputStream(fileName))) {
- ExcelWriter excelWriter = EasyExcel.write(out).build();
- WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
- int pageIndex = 0;
- List<Data> dataList;
- do {
- dataList = getDataByPage(pageIndex++, batchSize);
- excelWriter.write(dataList, writeSheet);
- } while (dataList.size() == batchSize);
- excelWriter.finish();
- } catch (IOException e) {
- e.printStackTrace();
- }
复制代码 6. 选择合适的数据导出工具
- 假如数据量非常大,可以考虑切换到支持更高性能的导出工具(如Apache POI的SXSSFWorkbook),适合导出百万级别数据量,但配置和使用会更复杂。
亮点来了,那要如何使用 POI 的 SXSSFWorkbook来导出百万级别的数据量呢?
Apache POI的SXSSFWorkbook 实现百万级别数据量的导出案例
使用Apache POI的SXSSFWorkbook可以处理大数据量的Excel导出,因为SXSSFWorkbook基于流式写入,不会将所有数据加载到内存中,而是使用暂时文件举行缓存,这样可以显著淘汰内存斲丧,适合百万级别数据的导出。下面我们来看一个完整的实现示例。
代码如下
来解释一下代码
- SXSSFWorkbook:SXSSFWorkbook(100)表现内存中最多保存100行数据,超过的部分会写入暂时文件,节省内存。
- 批次处理:通过batchSize控制每批次写入的数据量,以淘汰内存斲丧。totalRows设置为1,000,000表现导出100万条数据。
- 模仿数据天生:getDataBatch方法模仿分页获取数据,每次返回一批数据。
- 清除缓存行:每次写入一批数据后,通过flushRows(batchSize)将缓存的行从内存中清除,以控制内存占用。
- 压缩暂时文件:workbook.setCompressTempFiles(true)启用暂时文件压缩,进一步淘汰磁盘空间占用。
需要注意的事项
- 暂时文件:SXSSFWorkbook会在体系暂时文件夹中天生暂时文件,需要确保磁盘空间充足。
- 资源释放:完成数据写入后需要调用workbook.dispose()以清理暂时文件。
- 性能优化:可根据机器内存调整batchSize和SXSSFWorkbook缓存行数,避免频繁刷新和内存溢出。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |