Большие наборы данных PHPExcel с несколькими вкладками - исчерпана память

Используя PHPExcel, я могу запускать каждую вкладку отдельно и получать нужные результаты, но если я добавлю их все в один excel, он просто остановится, без ошибок или чего-то еще.

Каждая вкладка содержит от 60 до 80 тысяч записей, а у меня от 15 до 20 вкладок. Таким образом, около 1600000 записей разбиты на несколько вкладок (это число, вероятно, также будет расти).

Также я протестировал ограничение в 65000 строк с .xls, используя расширение .xlsx без проблем, если я запускаю каждую вкладку в своем собственном файле excel.

Псевдокод:

читать данные из базы данных запустить процесс PHPExcel анализировать данные для каждой страницы (некоторые стили/форматирование, но не много) (каждое числовое значение поля суммируется в столбце итогов в нижней части excel с использованием формулы SUM) сохранить excel ( формат xlsx)

У меня 3 ГБ ОЗУ, так что это не проблема, и скрипт настроен на выполнение без тайм-аута.

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

У всех есть такая проблема? работать вокруг? Советы? так далее...

ОБНОВИТЬ:

в журнале ошибок --- память исчерпана

Помимо добавления большего объема оперативной памяти в коробку, есть ли какие-либо другие советы, которые я мог бы сделать?

Кто-нибудь каждый раз сохраняет текущее состояние и редактирует excel с новыми данными?


person Phill Pafford    schedule 01.11.2011    source источник
comment
Вы проверяли журнал ошибок? Каков предел памяти php? Вполне возможно, что скрипт пытается выделить больше оперативной памяти, чем разрешено.   -  person Maerlyn    schedule 01.11.2011
comment
хрень в логе ошибок---память исчерпана   -  person Phill Pafford    schedule 01.11.2011
comment
Вы можете просто увеличить лимит памяти до точки, в которой она работает. Если это конкретный скрипт, я не вижу, чтобы он вызывал какие-либо проблемы на вашем компьютере. например ini_set('memory_limit', '32M');   -  person Shai Mishali    schedule 01.11.2011
comment
У меня та же проблема... Я пишу электронную таблицу в файл xml, затем конвертирую в xls/xlsx с помощью PHPExcel - не работает с большими файлами... У меня 32 ГБ памяти на моем сервере, и я выделяю ему 10 ГБ (PHP ) - большие файлы не записываются даже при таком объеме памяти!   -  person Manse    schedule 01.11.2011
comment
Это не физическая память, а memory_limit, установленный в вашем php.ini.   -  person Maerlyn    schedule 01.11.2011
comment
Мне часто приходится работать с наборами данных из более чем миллиона записей. Обычно, когда мне нужно поместить что-то в Excel, когда у меня так много данных, мой PHP выводит текстовый файл с разделителями и импортирует его в сам Excel. Но это может не всегда работать, особенно если вы включаете форматирование и другие причудливые вещи в свои электронные таблицы.   -  person Kevin Collins    schedule 01.11.2011
comment
Спасибо за советы, это проблема с памятью в библиотеке PHPExcel, и для ее работы требуется физическая память. Я установил ограничение памяти в PHP более 3 ГБ, и это все еще проблема. Прочитав множество сообщений об этом на форуме PHPExcel, это кажется ограничением.   -  person Phill Pafford    schedule 01.11.2011


Ответы (1)


У меня была точно такая же проблема, и поиск в Google не нашел ценного решения.

Поскольку PHPExcel генерирует объекты и сохраняет все данные в памяти, прежде чем, наконец, сгенерировать файл документа, который сам также хранится в памяти, установка более высоких ограничений памяти в PHP никогда полностью не решит эту проблему - это решение не очень хорошо масштабируется.

Чтобы действительно решить проблему, вам нужно сгенерировать файл XLS «на лету». Это то, что я сделал, и теперь я могу быть уверен, что «загрузить набор результатов SQL как XLS» работает независимо от того, сколько (миллионов) строк возвращается базой данных.

К сожалению, я не смог найти ни одной библиотеки, в которой реализована генерация XLS(X) "drive-by".

Я нашел эту статью в IBM Developer Works, в которой приводится пример того, как генерировать XLS XML «на лету»: http://www.ibm.com/developerworks/opensource/library/os-phpexcel/#N101FC

У меня работает очень хорошо - у меня есть несколько листов с МНОЖЕСТВОМ данных, и я даже не касался ограничения памяти PHP. Очень хорошо масштабируется.

Обратите внимание, что в этом примере используется обычный XML-формат Excel (расширение файла «xml»), поэтому вы можете отправлять несжатые данные непосредственно в браузер. http://en.wikipedia.org/wiki/Microsoft_Office_XML_formats#Excel_XML_Spreadsheet_example

Если вам действительно нужно создать XLSX, все становится еще сложнее. XLSX — это сжатый архив, содержащий несколько XML-файлов. Для этого вы должны записать все свои данные на диск (или в память - та же проблема, что и с PHPExcel), а затем создать архив с этими данными. http://en.wikipedia.org/wiki/Office_Open_XML

Возможно, также можно генерировать сжатые архивы «на лету», но такой подход кажется очень сложным.

person Kaii    schedule 19.11.2011
comment
Вау, отличный ответ! Я должен буду попробовать это и попытаться опубликовать некоторые результаты. - person Phill Pafford; 19.11.2011
comment
Спасибо @kaii, извините, мне все еще нужно проверить это, что может занять пару недель, но если это решит мою проблему, я сделаю это принятым ответом. Еще раз спасибо за ваши усилия, +1 был от меня. И да, пример кода всегда приветствуется :) - person Phill Pafford; 21.11.2011
comment
код не лучшего качества, но он дает пример того, как это сделать: pastebin.com/k1LHbz3W - person Kaii; 22.11.2011
comment
@PhillPafford, могу я спросить вас (уже два года спустя), смогли ли вы решить свою проблему? Возможно, вы нашли библиотеку php-excel, в которой нет этого ограничения? - person Kaii; 10.09.2013