导出excel遇到的问题

在开发中,使用SXSSFWorkbook构建导出excel时,可能会遇到“Attempting to write a row[?] in the range [0,?]that is already written to disk.”的报错情况,如下图所示。

 
对于这种情况下,需要我们详细分析,首先时这个错误时从哪儿抛出的,通过源码分析,查看到在SXSSFSheet的createRow函数中找到这样一个抛出异常的位置。
 
    ... if (rownum <= this._writer.getLastFlushedRow()) { throw new IllegalArgumentException("Attempting to write a row[" + rownum + "] " + "in the range [0," + this._writer.getLastFlushedRow() + "] that is already written to disk."); } else if (this._sh.getPhysicalNumberOfRows() > 0 && rownum <= this._sh.getLastRowNum()) { throw new IllegalArgumentException("Attempting to write a row[" + rownum + "] " + "in the range [0," + this._sh.getLastRowNum() + "] that is already written to disk."); }

分析这段异常的原因,当前要创建的行小于等于最近已经创建的行时,就会抛出异常。因此这个要求是,我们不能在已经创建行的位置再创建行

究其原因,是在于SXSSFWorkbook的本身实现方式,其本身实现方式在于,不断的将一定行数的表格写入临时文件,最终将所有的临时文件合并起来,这种方式中保证了内存的占用数理想,并且导出的效率也比较理想。

在这种实现中,如果一个行已经写入临时文件了,就不能再修改了,因此在源代码中直接限制了重复创建并写同一栏,并在此抛出异常。

解决方案

1、使用HSSFWorkbook、XSSFWorkbook替代SXSSFWorkbook。这种方式中要么是在HSSFWorkbook中仅支持xls,并且导出的数量有限,并且导出文件效率也较低,内存占用较大;虽然在XSSFWorkbook中,导出效率提高了,使用了xlsx格式,导出数量限制也大大放宽,但是内存占用问题依然没有得到解决。

2、避免在已经创建的行上重新创建行,使用getRow代替重复创建的情况。

:多数情况下,这种情况的出现,都是因为程序行数计数标志出现了重复、计数错误等情况导致的。

 

引用 自 https://www.jianshu.com/p/46616cc3ff61?utm_source=oschina-app

 
posted @ 2018-12-26 15:56  w_z_y  阅读(1457)  评论(0编辑  收藏  举报