java - 关于 SXSSFWorkbook 关于 FlushedRows、Written to Disk 和 rowAccessWindowSize 的问题

标签 java apache-poi

我需要在现有模板(.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”如何写入磁盘以及我应该进一步做什么?

所以对这三个产生了疑问,

  1. 什么是 FlushedRows 以及当我尝试创建新行时它如何刷新行 106403?

  2. 什么是“写入磁盘”?

  3. 使用参数“rowAccessWindowSize”初始化“SXSSFWorkbook”时,在我的例子中,它是 200,rowAccessWindowSize 是什么以及它会做什么?

最佳答案

SXSSFWorkbook仅供写作。当模板 XSSFWorkbook使用,然后在创建 SXSSFWorkbook 时从那XSSFWorkbookXSSFWorkbook 中的每个工作表创建一个临时文件这些工作表中的所有现有行都将写入这些临时文件中。稍后只有新行可以流入这些临时文件中。

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/

相关文章:

java - 使用 createNativeQuery 调用 Oracle 存储过程

java - Swing - 是否可以在 JTable 单元格中设置 'specific' 文本的字体颜色?

java - 记录属性的默认值

android - 有没有在Android上阅读MS Office PPT的代码?

java - 使用 Apache POI 时某些单元格不可见 - Java

java - 使用 IMAP 邮寄 : How to detect that a message has been moved from one folder to another?

java - 无法从外部库加载主类 list 属性

java - Apache POI 使用希腊语读取 excel xlsx

java - 如何获取函数表达式 Apache POI

java - 如何格式化 POI 创建的 Excel 文档