API для написания огромных файлов Excel с помощью Java

StackOverflow https://stackoverflow.com/questions/1486120

  •  18-09-2019
  •  | 
  •  

Вопрос

Я хочу написать в файл Excel (.xls MS Excel 2003 Format) программатически с использованием 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();

Очевидно, что написание рядов ~ 20 тыс. (С около 10-20 столбцов в каждом ряду) дает мне страшное «java.lang.outofmemoryerror: java huep space».

Я попытался увеличить начальный размер HEAPSIZE и максимальный размер кучи, используя параметры XMS и XMX в виде XMS512M и XMX1024. Все еще не могу написать в файл более 150 тысяч строк.

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

Это было полезно?

Решение

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

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

Другие советы

Попробуй использовать SXSSF Рабочая тетрадь, это здорово для огромных документов XLS, его строительного документа и вообще не ешьте ОЗУ, потому что используя NIO

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

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

Взглянуть на HSSF Serializer от проекта Cocoon.

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

Также есть Jexcelapi, но он использует больше памяти. Я думаю, что вы должны создать файл .csv и открыть его в Excel. Это позволяет вам передавать много данных, но вы не сможете выполнить «магию Excel».

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

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

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

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

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

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

Пока что Apache Poi - единственный выбор, который я нашел.

«Очевидно, что написание рядов ~ 20 тыс. (С около 10-20 столбцов в каждом ряду) дает мне страшное« java.lang.outofmemoryerror: пространство из кучи Java ».

"Enterprise It"

То, что вы можете сделать,- это выполнить вставку пакетов данных. Создайте таблицу Queuetask, каждый раз после генерации 1 -й страницы, отдыхайте на секунды, затем продолжайте вторую часть. Если вы беспокоитесь о динамических изменениях данных во время задачи очереди, вы можете сначала получить первичный ключ в Excel (скрывая и заблокируя столбец из представления пользователя). Сначала запуск будет вставить первичный ключ, а затем запуск второй очередь будет зачитываться из блокнота и выполнять часть задачи по участке.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top