java使用Workbook workbook = new XSSFWorkbook(inputStream);导出数据频繁GC

由于xlsx底层使用xml存储,占用内存会比较大,官方也意识到这个问题,在3.8版本之后,提供了SXSSFWorkbook来优化写性能

原来代码

Workbook workbook = newXSSFWorkbook(inputStream);

优化后代码

Workbook workbook = new SXSSFWorkbook(new XSSFWorkbook(inputStream));

此处有坑,请往下看

坑一:为什么模板中的数据获取不到?

当你企图使用SXSSFWorkbook去加载一个已存在的Excel模板时,首先你应该用XSSFWorkbook去获取

   XSSFWorkbook(java.io.File file) 
   XSSFWorkbook(java.io.InputStream is) 
   XSSFWorkbook(OPCPackage pkg) 
   XSSFWorkbook(java.lang.String path)

上列举了常用的四种获取XSSFWorkbook的方式。接下来如果你要对这个Excel模板做大量行列操作时,如果用XSSF的create方法势必会导致内存溢出。于是我们要使用SXSSFWorkbook去完成这个操作。

根据我对SXSSFWorkbook的了解,它只会加载一部分数据到内存,其余的数据全部持久化到本次磁盘。

但是当你噼里啪啦对SXSSFWorkbook进行了一顿操作时,你会发现SXSSFSheet.getRow(0) = null

这是因为这些记录存在于XSSFWorkbook中,你需要用sxssfWorkbook.getXSSFWorkbook()方法去获取初始模板的行数据。

需要改成这样:
Workbook workbook = new SXSSFWorkbook(new XSSFWorkbook(inputStream)).getXSSFWorkbook();

坑二:报错:Attempting to write a row[0] in the range [0,0] that is already written to disk

目前还不清楚这个报错是什么原因 在网上搜索有人说是由于你用XSSFWorkbook获取Excel模板的时候已经存在了行,然后用SXSSFWorkbook在Create这行的时候会报这个错误

但是当我把Workbook workbook = newXSSFWorkbook(inputStream);改成Workbook workbook = new SXSSFWorkbook(new XSSFWorkbook(inputStream));后这个报错也随之解决了,why??

 
posted @ 2024-04-18 09:47  p_小白  阅读(787)  评论(0编辑  收藏  举报

你再瞅我 还瞅!关注啊