Еще один способ генерации PDF. Бесплатный PDF Генератор от PDF24 на вашем компьютере или онлайн Создаем колонтитул страницы и вводный текст

11.03.2024

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

У отдельных клиентов отчёты представляют из себя большие pdf на десятки тысяч страниц. Само собой такие отчёты весят гигабайты и генерация их занимает продолжительное время. Столкнувшись с очередным ростом размера отчёта, мы решили проанализировать нашу архитектуру генерации pdf.

Традиционно в вебе генерация pdf состоит из двух этапов:

  • Генерация html страницы, которая потом станет pdf
  • Перевод html в pdf
  • Первый этап в нашем случае занимал достаточно мало времени, а вот второй мог длиться больше часа. Поэтому мы сделали небольшое сравнение какие существуют опенсорсные возможности по генерации pdf:

    Command being timed: "phantomjs --ssl-protocol=any ./capture.js 1.html 1.pdf" User time (seconds): 2240.56 System time (seconds): 6.96 Percent of CPU this job got: 83% Elapsed (wall clock) time (h:mm:ss or m:ss): 44:35.89 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 1821840 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 28 Minor (reclaiming a frame) page faults: 489364 Voluntary context switches: 53462 Involuntary context switches: 31797 Swaps: 0 File system inputs: 4576 File system outputs: 233848 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0

    Command being timed: "/usr/bin/google-chrome-stable --headless --disable-gpu --print-to-pdf 1.html" User time (seconds): 54.22 System time (seconds): 7.32 Percent of CPU this job got: 5% Elapsed (wall clock) time (h:mm:ss or m:ss): 18:49.74 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 951796 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 2 Minor (reclaiming a frame) page faults: 938614 Voluntary context switches: 184497 Involuntary context switches: 37463 Swaps: 0 File system inputs: 368 File system outputs: 174352 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0

  • Wkhtmltopdf Command exited with non-zero status 1 Command being timed: "wkhtmltopdf 1.html 1.pdf" User time (seconds): 3356.13 System time (seconds): 7.12 Percent of CPU this job got: 99% Elapsed (wall clock) time (h:mm:ss or m:ss): 56:21.54 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 3457744 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 8 Minor (reclaiming a frame) page faults: 977440 Voluntary context switches: 38567 Involuntary context switches: 47975 Swaps: 0 File system inputs: 1240 File system outputs: 197480 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 1
  • Из преведенного теста видно, что лучший результат получается у chrome, потом в два раза хуже phantomJs, а потом ещё значительно хуже Wkhtmltopdf. Этот результат перекликается с проблемами с разработкой phantomJs

    C другой стороны chrome зависит от X11, так что на сервере вопросов с ним будет значительно больше чем с phantomJs.

    Если делать небольшой вывод, то для тестирования машине с десктопом chrome безусловный победитель. На сервере его разумно использовать, если не бояться поставить туда X11, иначе phantomJs будет оптимальным вариантом

    Для того, чтобы генерировать PDF файл из HTML, мы будем использовать библиотеку DomPDF для PHP. И вместе с ней мы сможем получить качественно сгенерированные PDF файлы с русскими символами.

    Итак, приступим. Для начала необходимо скачать саму библиотеку по адресу:

    Или установить её через composer:

    Composer require dompdf/dompdf

    Однако, стоит отметить, что стандартная сборка НЕ поддерживает русскоязычные символы. Поэтому, приходится долго копать интернет и пробовать, пробовать, пробовать. Чтобы сократить Ваше время, мы уже собрали все. Ниже, Вы сможете скачать библиотеку с поддержкой русскоязычных символов.

    Если Вы хотите использовать стандартную сборку, то просто замените файлы из данного архива (916 KB) .

    Вам необходимо будет заменить файлы в папке:

    ../dompdf/lib/fonts

    С данным скриптом Вы сможете формировать сложные PDF файлы с таблицами, изображениями, которые из HTML встроятся в PDF файл.

    Мы используем эту библиотеку для генерации PDF при ajax запросе. В скачанном архиве Вы найдете файл index.php, который обрабатывает приходящие данные, подключает шаблон, в который уже встроены изображения. Мы выгрузили для Вас полностью рабочий и используемый нами вариант (5 MB) .

    Скачать пример сгенерированного PDF файла (580 KB)

    Если Вы скачали библиотеку, то подключите к Вашему PHP файлу её с помощью подключения автозагрузчика:

    Require_once "dompdf/autoload.inc.php";

    Или используйте GIT:

    Git clone https://github.com/dompdf/dompdf.git
    cd dompdf
    git clone https://github.com/PhenX/php-font-lib.git lib/php-font-lib
    cd lib/php-font-lib
    git checkout 0.5.1
    cd ..
    git clone https://github.com/PhenX/php-svg-lib.git php-svg-lib
    cd php-svg-lib
    git checkout v0.3

    Сам обработчик выглядит так:

    //подключаем автозагрузчик include_once "autoload.inc.php"; //функция очистки кода от вредоносных данных function challsrt($data){ $array1=array("\"","*","%","0x","&","\0","\n","\r","\s","\t","\\","`","^","$","{","}","[","]","(",")","wss","blob","localhost","–","