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??