Итак, теперь, когда у нас есть пригодная для использования трассировка стека, ясно, что проблема не возникает при записи файла CSV. Это на самом деле происходит, когда вы оцениваете формулу электронной таблицы. Я предполагаю, что формула суммируется по всем строкам на листе ... или что-то в этом роде.
Это проблема, и, вероятно, не существует простого решения.
Вот что Документация по POI говорит:
Размеры файлов / Использование памяти
- Существуют некоторые внутренние ограничения в форматах файлов Excel. Они определены в классе
SpreadsheetVersion
. Пока у вас достаточно основной памяти, вы сможете обрабатывать файлы до этих пределов. Для больших файлов, использующих классы POI по умолчанию, вам, вероятно, понадобится очень большой объем памяти. - Существуют способы преодоления ограничений основной памяти, если необходимо:
- Для записи очень больших файлов существует
SXSSFWorkbook
, который позволяет выполнять потоковую запись данные в файлы (с некоторыми ограничениями на то, что вы можете делать, так как в памяти хранятся только части файла). - Для чтения очень больших файлов посмотрите пример
XLSX2CSV
, который показывает, как вы можете читать файл в потоковом режиме (опять же, с некоторыми ограничениями на то, какую информацию вы можете прочитать из файла, но есть способы получить максимум информации при необходимости).
Вы явно сталкиваетесь с этими ограничениями памяти. По сути, POI пытается загрузить слишком много электронной таблицы в память ... пока вы оцениваете формулы электронной таблицы ... и вы заполняете кучу.
Одним из решений было бы увеличение Java размер кучи. Или, если вы уже используете всю доступную оперативную память для своей кучи, запустите преобразование на машине с большим объемом оперативной памяти. В наши дни многие стандартные ПК имеют 16 ГБ ОЗУ. Может быть, пришло время для обновления оборудования? Но я предполагаю, что вы уже подумали об этом.
Если увеличение размера кучи нежизнеспособно, вам придется переписать приложение, чтобы использовать SXSSFWorkbook
. Кроме того, вам может потребоваться заменить подход, основанный на использовании формулы, на вычисления в нативном Java способом, совместимым с построчным потоковым потоком электронной таблицы . (Это будет зависеть от того, что делают формулы.)
Посмотрите на связанный пример из документации POI для идей.