Как обрабатывать ЧРЕЗВЫЧАЙНО большие строки в PHP при создании PDF

У меня есть отчет, который может генерировать более 30 000 записей, если задан достаточно большой диапазон дат. С точки зрения HTML такой большой набор результатов не является проблемой, поскольку я реализовал систему разбиения на страницы, которая ограничивает видимые результаты до 100 в данный момент времени.

Моя настоящая проблема возникает, когда пользователь нажимает кнопку «Получить PDF». Когда это происходит, я повторно запускаю часть отчета, которая распечатывает данные (результаты самого отчета хранятся в таблице «сохранения», поэтому нет необходимости повторно запускать данные). логика сбора) и сохранить результаты в переменной с именем $html. Имейте в виду, что эта переменная теперь содержит 30 000 записей данных плюс HTML, необходимый для правильного форматирования в PDF. Создав эту HTML-строку, я передаю ее в TCPDF, чтобы попытаться сгенерировать PDF-файл для пользователя. Однако вместо создания файла PDF он просто вылетает без сообщения об ошибке (диалоговое окно «Создание PDF...») исчезает, и система ведет себя так, как будто вы никогда не просили ее что-либо сделать.

С помощью тестов я обнаружил, что проблема заключается в размере передаваемой переменной $html. Если отчет под 3K записей, он работает нормально. Если это больше, будет распечатана часть отчета в формате HTML, но не в формате PDF.

Полезная информация

  • PHP 5.3
  • TCPDF для генерации PDF (также пробовал PS2PDF)
  • Ограничение памяти сценария: 500 МБ

Как бы вы, ребята, справились с этим масштабом данных при создании PDF-файла такого размера?


person Levi Hackwith    schedule 26.08.2010    source источник


Ответы (4)


TCPDF кажется собственной реализацией генерации PDF в PHP. Вы можете повысить производительность, используя скомпилированную библиотеку, такую ​​как PDFlib, или команду -line, например htmldoc. Последний будет иметь наилучшие шансы на создание большого PDF-файла.

Кроме того, вы разбиваете выходной PDF-файл на несколько страниц? т.е. знает ли TCPDF, что нужно взять один HTML-документ и разрезать его на несколько страниц, или вы создаете несколько HTML-файлов, чтобы объединить их в один PDF-документ? Это также может помочь.

person Lèse majesté    schedule 26.08.2010
comment
Я передаю одну гигантскую строку HTML, которую TCPDF затем разбивает на многостраничный PDF-файл. Думаю проблема не в генераторе PDF, а в большом размере переменной $html. - person Levi Hackwith; 26.08.2010
comment
@Levi Hackwith: Это не имеет никакого смысла. PDF-файлы могут быть любого размера. Если генератор PDF дает сбой, когда его входной HTML-код слишком велик, то это проблема с генератором. В противном случае просто уменьшите размер вашего HTML-файла и создайте много небольших PDF-файлов, как предлагает shamittomar. Хотя у большинства настольных программ нет проблем с созданием PDF-файлов с более чем 100 000 страниц. - person Lèse majesté; 26.08.2010
comment
Итак, все согласны с тем, что проблемы кроются в TCPDF, а не в самом PHP? - person Levi Hackwith; 26.08.2010
comment
@Levi Hackwith: Если скрипт не превышает максимальное время выполнения скрипта или лимит памяти скрипта, это вряд ли будет проблемой с PHP. Я также очень сомневаюсь, что вам потребуется более 500 МБ для создания PDF-файла, если только каждая запись сама по себе не огромна. Но вы всегда можете проверить с помощью memory_get_peak_usage(). - person Lèse majesté; 26.08.2010
comment
получает ответ, так как он предложил весь подход к командной строке, который будет лучшим способом справиться с этим - person Levi Hackwith; 28.08.2010

Вот как я решил эту проблему: я заметил, что некоторые из строк, которые я имел в своем выводе HTML, имели небольшие проблемы с кодировкой - я запускал htmlentities для этих конкретных строк, когда запрашивал базу данных для их, и это устранило проблему.

Не знаю, было ли это причиной вашей проблемы, но мой опыт был очень похож - когда я пытался вывести HTML-таблицу большого размера, содержащую около 80 000 строк, TCPDF отображал заголовок страницы, но ничего не отображал. Связанный. Это поведение будет одинаковым для разных наборов данных и разных структур таблиц.

После многих попыток я начал добавлять свою собственную разбивку на страницы - каждые 15 строк таблицы я разбивал страницу и добавлял новую таблицу на следующую страницу. Именно тогда я заметил, что время от времени я получаю пустые страницы между множеством полных и правильных страниц. Именно тогда я понял, что должна быть проблема с этими конкретными подмножествами данных, и обнаружил проблему с кодировкой. Возможно, у вас было что-то подобное, и TCPDF не давал понять, в чем ваша проблема.

person Petre Pătraşc    schedule 10.01.2012

Вы используете метод writeHTML?

Я ознакомился с рекомендациями по производительности здесь: http://www.tcpdf.org/performances.php.

В нем говорится: «Разделить большие блоки HTML на более мелкие части;».

Я обнаружил, что если мои блоки HTML превышают 20 000 символов, создание PDF-файла займет более 2 минут.

Я просто разделил свой html на блоки и вызвал writeHTML для каждого блока, и результат значительно улучшился. Файл, который не сгенерировался за 2 минуты до этого, теперь занимает 16 секунд.

person Jonny White    schedule 26.01.2012

Я бы разбил PDF на части, как нумерацию страниц.

1) Иметь кнопку «Получить PDF» на каждой HTML-странице с разбивкой на страницы и разрешать загрузку записей только с этой HTML-страницы.

2) Ограничьте максимальное количество записей, которые можно скачать. Если достигнут максимальный предел, разделите PDF-файл и позвольте пользователю загрузить несколько PDF-файлов.

person shamittomar    schedule 26.08.2010