Вопросы по SXSSFWorkbook о его FlushedRows, записанных на диск и rowAccessWindowSize - PullRequest
0 голосов
/ 06 июля 2019

Мне нужно записать миллионы записей в файл Excel (.xlsx) на уже существующий шаблон (.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: попытка записиrow[0] в диапазоне [0,106403], который уже записан на диск "

Я совсем не уверен, как" 106403 "записывается на диск и что мне делать дальше?

Так возникает сомнение в этих трех,

  1. Что такое FlushedRows и как он очищает строки 106403, когда я пытаюсь создать новую строку?

  2. Что такое «Запись на диск»?

  3. При инициализации «SXSSFWorkbook» с параметром «rowAccessWindowSize», в моем случае это 200 и что такое rowAccessWindowSize и что оно будет делать?

1 Ответ

1 голос
/ 06 июля 2019

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);.Позже только строки, которые больше номера строки 106405, могут быть созданы новыми в SXSSFSheet.

...