API для создания огромных файлов excel с использованием java

Я хочу писать в формате excel (.xls MS Excel 2003) программно с помощью Java. Выходные файлы excel могут содержать ~ 200 000 строк, которые я планирую разделить на количество листов (64k строк на листе из-за предела excel).

Я попытался использовать API-интерфейс apache POI, но, похоже, это зависание памяти из-за объектной модели API. Я вынужден добавлять ячейки/листы к объекту книги в памяти, и только после того, как все данные будут добавлены, я могу написать книгу в файл! Вот пример того, как apache рекомендует писать файлы excel с помощью их API:

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");

//Create a row and put some cells in it
Row row = sheet.createRow((short)0);

// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Очевидно, что запись строк ~ 20k (с примерно 10-20 столбцами в каждой строке) дает мне ужасное "java.lang.OutOfMemoryError: Java heap space".

Я попытался увеличить начальный размер кучи JVM и максимальный размер кучи, используя параметры Xms и Xmx как Xms512m и Xmx1024. Все еще не могу записать в файл более 150 тыс. Строк.

Я ищу способ переместить файл excel вместо создания всего файла в памяти, прежде чем записывать его на диск, который, мы надеемся, сэкономит много памяти. Любые альтернативные API или решения будут оценены, но я ограничусь использованием java. Благодарю!:)

Ответы

Ответ 1

Все существующие Java-API пытаются сразу создать весь документ в ОЗУ. Попробуйте написать XML файл, который соответствует новому файлу формата xslx. Чтобы начать работу, я предлагаю создать небольшой файл в желаемой форме в Excel и сохранить его. Затем откройте его и проверьте структуру и замените нужные вам детали.

В Википедии есть хорошая статья об общем формате.

Ответ 2

Попытайтесь использовать SXSSF книгу, это замечательно для огромных документов xls, его документа сборки и вообще не есть RAM, потому что используйте nio

Ответ 3

Мне пришлось разбить файлы на несколько файлов excel, чтобы преодолеть исключение кучи пространства. Я подумал, что около 5 тыс. Строк с 22 столбцами было около того, поэтому я просто сделал свою логику, чтобы каждая строка в 5 тыс. Окончила файл, начинала новую и просто составляла нумерацию файлов.

В тех случаях, когда у меня было написано 20k + строк, у меня было бы 4 разных файла, представляющих данные.

Ответ 4

Посмотрите сериализатор HSSF из проекта кокона.

Сериализатор HSSF ловит события SAX и создает электронную таблицу в формате XLS, используемом Microsoft Excel

Ответ 5

Также есть JExcelApi, но он использует больше памяти. Я думаю, вы должны создать файл .csv и открыть его в excel. он позволяет передавать много данных, но вы не сможете совершать какие-либо "магии excel".

Ответ 6

Рассмотрим формат CSV. Таким образом, вы больше не ограничены памятью - возможно, только при предварительном заполнении данных для CSV, но это также можно сделать эффективно, например, запросить подмножества строк из БД, используя, например, LIMIT/OFFSET, и сразу написать вместо того, чтобы переписывать содержимое всей таблицы БД в память Java, прежде чем писать какую-либо строку. Ограничение Excel строк количества в одном "листе" увеличится примерно до миллиона.

Тем не менее, если данные на самом деле поступают из БД, я бы очень пересмотрел, если Java является правильным инструментом для этого. У большинства достойных БД есть функция export-to-CSV, которая может сделать эту задачу, несомненно, намного более эффективной. В случае, например, для MySQL, вы можете использовать LOAD DATA INFILE для этого.

Ответ 7

Мы разработали Java-библиотеку для этой цели, и в настоящее время она доступна в виде проекта с открытым исходным кодом https://github.com/jbaliuka/x4j-analytic. Мы используем его для оперативной отчетности. Мы генерируем огромные файлы Excel, ~ 200 000 должны работать без проблем, Excel тоже удается открыть такие файлы. В нашем коде используется POI для загрузки шаблона, но сгенерированный контент передается непосредственно в файл без слоя XML или объектной модели в памяти.

Ответ 8

Является ли эта проблема с памятью, когда вы вставляете данные в ячейку или когда выполняете вычисления/генерации данных?

Если вы собираетесь загружать файлы в excel, которые состоят из предопределенного статического формата шаблона, то лучше сохранить шаблон и повторно использовать его несколько раз. Обычно случаи шаблонов случаются, когда вы собираетесь генерировать ежедневный отчет о продажах и т.д....

Else, каждый раз, когда вам нужно создавать новую строку, границу, столбец и т.д. с нуля.

До сих пор Apache POI - единственный выбор, который я нашел.

"Очевидно, что запись строк ~ 20k (с примерно 10-20 столбцами в каждой строке) дает мне ужасное" java.lang.OutOfMemoryError: Java кучу пространства ".

"Предприятие ИТ"

ЧТО ВЫ МОЖЕТЕ СДЕЛАТЬ - выполнить вставку пакетных данных. Создайте таблицу queuetask, каждый раз после создания 1 страницы, отдыхайте в секундах, затем продолжайте вторую часть. Если вы беспокоитесь о динамических изменениях данных во время задачи очереди, вы можете сначала перенести первичный ключ в excel (скрыв и заблокировав столбец из пользовательского вида). Первый запуск будет вставлять первичный ключ, затем второй запуск очереди будет считываться из блокнота и выполнять часть задачи по частям.

Ответ 9

Мы сделали что-то очень похожее, столько же данных, и нам пришлось переключиться на JExcelapi, потому что POI настолько тяжел для ресурсов. Попробуйте JexcelApi, вы не пожалеете об этом, когда вам придется манипулировать большими Excel файлами!