我需要在现有模板(.xlsx) 上的Excel(.xlsx) 文件中写入数百万条记录。最初我使用的是 XSSFWorkbook,这显然导致了 OOM 问题。
后来,我改用SXSSFWorkbook来避免OOM问题,如下所示,
FileInputStream fis = new FileInputStream(file);
OPCPackage pkg = OPCPackage.open(fis);
XSSFWorkbook mainBook = new XSSFWorkbook(pkg);
SXSSFWorkbook wb = new SXSSFWorkbook(mainBook,200);
Sheet sh = wb.getSheet("Sheet1");
Row row0 = sh.createRow(0);
在 SXSSFWorkbook 中,我们无法修改现有模板,因此我将模板保留为空,以便也写入带有列标题的数据。
但是在 row0 = sh.createRow(0);
上,它抛出类似“java.lang.IllegalArgumentException: Attempting to write a row[0]
in已写入磁盘的范围[0,106403]
”
我完全不确定“106403”如何写入磁盘以及我应该进一步做什么?
所以对这三个产生了疑问,
什么是 FlushedRows 以及当我尝试创建新行时它如何刷新行 106403?
什么是“写入磁盘”?
使用参数“rowAccessWindowSize”初始化“SXSSFWorkbook”时,在我的例子中,它是 200,rowAccessWindowSize 是什么以及它会做什么?
最佳答案
SXSSFWorkbook仅供写作。当模板 XSSFWorkbook
使用,然后在创建 SXSSFWorkbook
时从那XSSFWorkbook
为 XSSFWorkbook
中的每个工作表创建一个临时文件这些工作表中的所有现有行都将写入这些临时文件中。稍后只有新行可以流入这些临时文件中。
rowAccessWindowSize
设置在刷新到临时文件之前保留在内存中的行数。已写入临时工作表文件的所有行以后都无法再访问,因为它们不再位于内存中,而仅位于临时文件中。这就是 SXSSF
内存使用率低的原因.
错误消息java.lang.IllegalArgumentException: Attempting to write a row[0] in the range [0,106403] that is already written to disk.
告诉您索引为 0 到 106403 的行(行 1 到 106404)已经写入磁盘。这告诉您您的模板表 Sheet1
不为空。至少第 106404 行必须有数据。这就是为什么第 1 到 106404 行被写入 Sheet1
' 的临时文件,而 SXSSFWorkbook wb = new SXSSFWorkbook(mainBook,200);
。稍后,只能在 SXSSFSheet
上创建大于行号 106405 的行。 .
关于java - 关于 SXSSFWorkbook 关于 FlushedRows、Written to Disk 和 rowAccessWindowSize 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56912475/