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 файлами!