2014-01-31 2 views
5

Пару лет назад я столкнулся с проблемами, когда создавал большие файлы Excel, используя jXLS и POI XSSF. Если моя память правильная, я думаю, что XSSF создаст что-то вроде 1GB + temp-файлов на диске, чтобы создать 10-миллиметровые файлы excel. Поэтому я прекратил использовать jXLS и вместо этого использовал SXSSF для создания файлов excel, но сегодня у меня есть новые причины для использования jXLS или JETT.Есть ли у POI XSSF сумасшедшие проблемы с памятью?

Оба jXLS и JETT сайты, кажется, намекают, что производительность намного лучше, но POI «s XSSF сайт по-прежнему говорит, в общем, что XSSF требует большего объема памяти. Я задаюсь вопросом, является ли этот более высокий объем памяти чем-то вроде разумных 10% -ных накладных расходов в эти дни, или если это все еще похоже на 10 000% накладных расходов, как это было пару лет назад.

Являются ли сумасшедшие проблемы с памятью исправленными с помощью POI 3,9 XSSF? Должен ли я не беспокоиться об использовании его с jXLS или JETT? Или есть определенные ошибки, которых нужно избегать? Я осторожен в повторном использовании стилей ячеек.

+1

Этот вопрос очень расплывчатый, но убедитесь сами, что произошло в выпуске: http://poi.apache.org/changes.html. Похоже, он не был явно рассмотрен. –

+0

Независимо от того, что вы делаете, для работы с '.xlsx' потребуется больше файлов памяти или temp, чем' .xls', поскольку накладные расходы всего XML и сжатия выше, чем двоичные форматы. – Gagravarr

+0

@James: знайте, как быть менее расплывчатым. Накладные расходы около 10% кажутся разумными, накладные расходы на 10 000% - нет. Я пытаюсь выяснить, есть ли накладные расходы памяти примерно на 10 000%, как раньше, или если он ближе к 10%. –

ответ

5

Чтобы ответить на ваш вопрос, да, POI всегда будет использовать очень большой объем памяти при работе с большими файлами XLSX, который намного больше размера файлов XLSX. Я не думаю, что это изменится в ближайшее время, и для этого есть довольно очевидные причины: XLSX - это, в основном, множество zipped-файлов XML, а XML очень хорошо сжат (около 10x). Получение этого XML просто для того, чтобы сидеть в несжатой памяти, уже увеличило бы потребление памяти в десять раз, поэтому, если вы добавите все накладные расходы структур данных, вы не сможете ожидать увеличения объема памяти в размере XLSX на 10%.

Теперь хорошая новость заключается в том, что, как упоминалось в комментариях, Apache POI представил SXSSF для потоковой передачи очень большого объема данных в электронной таблице с очень хорошей производительностью и низким объемом использования памяти. Файлы XLSX, созданные таким образом, по-прежнему передаются на жесткий диск, где они могут в конечном итоге занимать довольно много места, но по крайней мере вы не рискуете OOME при написании сотен тысяч строк.

Проблема в том, что вы не сможете заставить JETT напрямую работать с SXSSF, поскольку для выполнения заполнения шаблона требуется весь документ, загруженный в память. Автор JETT быстро обсудил этот вопрос here.

У меня была такая же проблема, и в конечном итоге делает создание XLSX двухступенчатый:

  1. Стандартный шаблон Джетт XLSX для создания заголовков и форматирования. Последняя строка первого листа содержит ячейки с $$ tokens $$, по одному на ячейку. Я не использую JETT для вставки большого количества строк.

  2. После того, как JETT выполнил свою работу, я снова открываю книгу, читаю, а затем удаляю $$ tokens $$ в последней строке первой электронной таблицы и запускаю потоковые данные с помощью строки SXSSF.

Конечно, есть ограничения этого подхода: - Вы не можете использовать Джетта на любом из потоковых строк при вставке строк (но вы можете перед тем, чтобы динамически выбрать порядок $$ лексем $$ например) - Формат ячеек не будет скопирован, если вы сами не позаботитесь об этом с помощью API POI. Я лично предпочитаю форматировать целые столбцы в моем XLSX-файле, и он будет применяться к потоковым данным.

Это также работает, если вы хотите отображать диаграммы с использованием данных, вставленных в SXSSF: вы можете определить Именованный диапазон с функциями OFFSET и COUNTA, а затем создать сводную таблицу & Сводная диаграмма, которая будет обновлена ​​при открытии XLSX в Excel ,

+0

Я не согласен с тем, что POI должен использовать большой объем памяти и/или огромные временные файлы. С логикой вашего ответа, Excel, OpenOffice и LibreOffice будут страдать от тех же проблем с памятью. –

+1

Я думаю, что реальная проблема заключается в том, что POI использует плохую структуру внутренней структуры данных. Я думаю, что в общем случае xml-файл в 12 раз больше, чем в zip. Во время создания отчета POI использует временный файл, который на 1000 раз больше, чем полученный xlsx, поэтому это определенно не просто сжатие, вызывающее проблему. –

+0

Я понял, что Excel/Office/LibreOffice может загружать огромные файлы XLSX без проблем, но я считаю, что эти программные средства должны использовать оптимизированную внутреннюю структуру, чтобы иметь возможность эффективно хранить данные, отображаемые в приложении. POI, с другой стороны, представляет собой библиотеку, начатую с интерфейсов для формата XLS, и поддерживает тот же интерфейс, что позволяет изменять формат XLSX, основанный на XML. Имеет смысл сохранить эквивалент структуры XML для внесения изменений, так как очень просто написать обратно формат XLSX, а не просматривать оптимизированную структуру данных. –

Смежные вопросы