Php генерация pdf из html. Сравнение способов генерации pdf из html


Генерация pdf-документов является повседневной задачей в веб-разработке. В перечень таких документов входят счета, накладные, полисы и прочие. Существует множество готовых библиотек для решения этой задачи, в том числе и для php. Например, mpdf ,tcpdf , и многие другие. Файл можно собрать с помощью api этих библиотек, но это довольно долгое занятие. А времени на реализацию задачи много не бывает, не так ли? Поэтому чаще всего pdf-файл создается из html-представления, что довольно удобно. Но, к сожалению, не все так просто. У такого подхода есть множество подводных камней, способных вывести из себя кого угодно.

Например:

  • Стили нельзя подключить отдельно, следовательно они должны быть включены в html-документ отдельным блоком, либо инлайново для каждого элемента. В этом нет ничего страшного, небольшое неудобство.
  • К сожалению, в таких библиотеках некоторые стили могут работать не так как этого от них ожидаешь, либо не работать в принципе. Это самый главный недостаток.
  • Из предыдущего пункта следует, что создать документ максимально соответствующий требованиям очень трудоемко, а порой просто невозможно.
  • А в случае разработки под Битрикс есть еще одна проблемка. Все знают, что для работы платформы требуется в php.ini установить параметр mbstring.func_overload в значение 2. А для создания pdf-файла, содержащего кириллицу потребуется значение 0. Обычно эта проблема решается с помощью настройки веб-сервера, но все равно неприятно.

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

Пришло время перейти к главной части этой статьи. Помимо вариантов предложенных выше, существует альтернативный - PhantomJS .

PhantomJS - это сборка движка WebKit без графического интерфейса, позволяющая в режиме консоли загружать веб-страницу, выполнять JavaScript, полноценно работать с DOM, Canvas и SVG.

Конечно, помимо перечисленных выше возможностей, он дает возможность создавать pdf-файлы.

Каким образом? Говоря простым языком, он загружает требуемую веб-страницу и дает возможность сохранить результат как pdf-файл.

Процесс установки PhantomJS достаточно подробно описан в документации , поэтому я не буду останавливаться на этом вопросе.

Важным моментом в работе PhantomJS является js-файл (далее config.js), который своим содержанием определяет то, что именно мы хотим сделать. На официальном сайте есть множество готовых примеров таких файлов, с помощью которых решаются самые разные задачи, например, unit-тестирование. В числе примеров есть сохранение веб-страницы в формате pdf . Это именно то, что нам нужно.

Пара небольших правок позволит использовать этот пример в наших целях.

var page = require ("webpage" ). create (), system = require ("system" ), address , output , size ; //если аргументов мало или слишком много, выводится сообщение с помощью по использованию if (system . args . length < 3 || system . args . length > 5 ) { console . log ("Usage: config.js URL filename " ); console . log (" paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"" ); console . log (" image (png/jpg output) examples: "1920px" entire page, window width 1920px" ); console . log (" "800px*600px" window, clipped to 800x600" ); phantom . exit (1 ); } else { // обработка аргументов address = system . args [ 1 ]; output = system . args [ 2 ]; page . viewportSize = { width : 800 , height : 800 }; if (system . args . length > 3 && system . args [ 2 ]. substr (- 4 ) === ".pdf" ) { size = system . args [ 3 ]. split ("*" ); page . paperSize = (size . length === 2 ) ? { width : size [ 0 ], height : size [ 1 ], margin : "0px" } : { format : system . args [ 3 ], orientation : "portrait" , margin : "1cm" }; } else { console . log ("Invalid path to pdf!" ); phantom . exit (1 ); } if (system . args . length > 4 ) { page . zoomFactor = system . args [ 4 ]; } // открытие страницы и сохранение результата page . open (address , function (status ) { if (status !== "success" ) { console . log ("Unable to load the address!" ); phantom . exit (1 ); } else { window . setTimeout (function () { page . render (output ); phantom . exit (); }, 200 ); } }); }

$ phantomjs path/to/config.js "url" path/to/pdf/file "A4"

Разберем аргументы по порядку:

  1. Путь до config.js.
  2. Адрес веб-страницы, которую надо преобразовать в pfd-файл.
  3. Путь до pdf-файла, в который произойдет сохранение результата.
  4. Формат pdf-файла.

Получаем искомый pdf-файл.

Возвращаясь к php, это решение довольно просто интегрировать в код.

В простейшем случае это выглядит вот так:

$command = sprintf( "phantomjs %s %s %s %s", $fullPathToConfigJS, $url, $fullPathToSave, $format ); exec($command);

Итак, подведу итоги. На мой взгляд, такое решение имеет следующие достоинства:

  • Сверстать макет для такого документа намного проще. Это очень важно, т.к. не только упрощает разработку, но и не превращает в кошмар последующие правки документа.
  • Избавляет от нужды извращаться с mbstring.func_overload. Но это, несомненно, проблема характерная в основном для Битрикс.

Конечно, есть и недостатки:

  • Не 100% поддержка всех css-стилей. Но в сравнении с библиотеками, перечисленными в начале стати, все очень хорошо.
  • Такое решение может отпугнуть начинающего разработчика.
03.12.2015

PDF24 Creator, это бесплатный PDF генератор для вашего ПК. Генерация PDF файлов невероятно простая задача с этой программой. Комбинация дополнительных возможностей вместе с созданием PDF файлов, делает этот инструмент одной из самых признанных бесплатных программ. В качестве альтернативы вы также можете генерировать PDF онлайн. Прочтите ниже как это работает.

PDF24 Creator – бесплатный PDF генератор

PDF24 Creator, это бесплатный PDF генератор для Windows. Генерация PDF файлов реализована с помощью PDF принтера. После установки в вашей Windows появится новый виртуальный PDF принтер. Просто печатайте через этот принтер все, что хотите превратить в PDF. PDF принтер, это единственный путь создания PDF. Программа включает в себя широкий диапазон возможностей, которые помогут вам в генерации PDF. Эта программа бесплатна. Вы можете скачать свежую версию с этого сайта.

PDF24 Онлайн PDF Генератор – Генерация PDF файлов онлайн

Онлайн PDF Генератор, это полезный инструмент, если вы хотите преобразовать документы в PDF формат. Просто выберите документ или отправьте документ по почте в Онлайн PDF Генератор и через несколько секунд ваш PDF файл будет доступен для скачивания или отправлен вам обратно.

Email интерфейс для этого PDF генератора также доступен. Нужно отправить файлы генератору и дождаться ответного письма, в котором будут файлы, сконвертированные в PDF

Множество других PDF генераторов в инструментарии PDF24

Онлайн утилиты от PDF24 решают многие проблемы, связанные с PDF, достаточно просто, быстро и бесплатно. Многие из этих инструментов генерируют PDF файлы. Вы ещё не знакомы с онлайн утилитами PDF24? Взгляните, вы сможете использовать все эти инструменты.

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

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

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

  1. Генерация html страницы, которая потом станет pdf
  2. Перевод 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

  1. 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 будет оптимальным вариантом

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

Почему PDF? Формат PDF позволяет создавать документы с целым рядом неоспоримых преимуществ: открытость, кроссплатформеность, распространенность и, что очень важно, точностью и неизменностью передачи данных по цепочке создание, просмотр и печать.

В чем соль? В использовании SVG файлов как шаблонов с возможностью подстановки необходимых полей с последующим преобразованием в PDF.

Какие преимущества? Возможность создания и быстрого редактирования очень сложных шаблонов в привычных векторных редакторах, таких как Adobe Illustrator, Corel Draw или Inkscape. Простота программирования и использование только бесплатных программных средств. Еще одним важным преимуществом является возможность прозрачно использовать UTF-8 для вставляемых текстов.

Что для этого надо? Для использования данного метода нужен выделенный сервер с возможностью установки своих приложений (Inkscape и GhostScript) и выполнением system-команд. При этом всё будет работать как на Windows платформе, так и на Linux.

Думаю, краткий FAQ осветил основные вопросы по данному методу, потому сразу приступим к разбору его сути.

Как известно, формат векторной графики SVG фактически представляет собой XML-файл, поэтому уже созданный файл достаточно просто редактировать простейшими средствами программирования. В случае использования SVG файла как жесткого шаблона, процесс упрощается в разы, т.к. нам нет необходимости менять структуру документа, а нужно лишь произвести подстановку нужных текстовых значений или кодированных в base64 растровых изображений.

Создать первоначальный шаблон можно в любом векторном редакторе поддерживающем экспорт в svg: Adobe Illustrator, Corel Draw или в самом Inkscape’е. Использование последнего желательно, хотя бы на последней, доводочной стадии, так как, в конечном счете, именно ему и предстоит производить необходимое нам преобразование.

При использовании растра в шаблоне, можно использовать 2-а метода, хранить растр в отдельном внешнем файле или встроенным в сам SVG файл. При необходимости менять в шаблоне растровый рисунок в первом случае можно перед генерацией менять и файл. При хранении рисунка встроенным в файл, следует в свойстве URL объекта рисунка прописать строку:

где {IMAGE} - это поле для вставки шаблонизатором base64 кодированного изображения.

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


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

Думаю, вы уже обратили внимание на то, что в местах предполагаемого текста вставлены тэги шаблонизатора (в данном примере использовался ). Именно использование XML совместимых тегов дает возможность прописывать их в самом векторном редакторе не прибегая к дополнительному редактированию.

Мы имеем шаблон, и уже без проблем сможем вставить необходимые нам данные, но как собственно мы будем проводить преобразование? Для этого воспользуемся интерфейсом командной строки Inkscape:

#преобразование в PDF-файл
inkscape -A

Используя ключ «-A » мы сразу получим PDF файл, но, к сожалению, создаваемый напрямик PDF имеет очень большие размеры. Для решения этой проблемы можно пойти в обход. А именно, использовать экспорт SVG не на прямую в PDF, а по цепочке SVG->PS->PDF . Использовав для конечного формирования PDF файла утилиту ps2pdf из комплекта Ghost Script, мы можем уменьшить размеры финального файла в десятки раз.
#преобразование в PostScript-файл
inkscape -P
#преобразование в PostScript-файла в PDF
ps2pdf

Единственный минус в том, что в этом случае мы потеряем все эффекты прозрачности, так как формат PostScript его не поддерживает.

Для полной переносимости сгенерированных документов, можно добавить Inscape’у опцию «-T » преобразования всего текста в кривые. Этим самым мы сможем избавиться от проблем наличием шрифтов на клиентской машине, а также от проблем с кодировками.

Теперь мы имеем, всё необходимое: SVG шаблон и команды преобразований. Напишем php-скрипт, который бы выдавал pdf-файл сгенерированный из шаблона.

/* ****************************************************************************************
* Скрипт формирования pdf-файла пропуска с помощью последовательного преобразования
* шаблона в svg файл, после чего тот преобразуется в PostScript файл программой Inkscape,
* и последний преобразуется в pdf с помощью утилиты ps2pdf.
*
* Автор: Шебастюк В.В. a.k.a. JStingo
* **************************************************************************************** */

/* параметры скрипта */

//Путь к папке с временными файлами
//(если не указан, то файлы будут хранится в системной временной папке)
$tmp_dir = "" ;//генерируем пути к временным svg, ps и pdf файлам
$tmp_svg_file = tempnam ($tmp_dir , "" );
$tmp_ps_file = tempnam ($tmp_dir , "" );
$tmp_pdf_file = tempnam ($tmp_dir , "" );/* Шаблонизатор FastTemplate */
include(«include/cls_fast_template.php» );
$tpl = new FastTemplate («templates» );try {/* Блок с получаемыми для шаблонизации данными */
/* ........................... */
$user_name = "JStingo" ;
$register_date = "28/09/2007" ;
/* ........................... */
/* формируем имя результрующего файла в виде User_name.pdf */
$pdf_file_name = $user_name . ".pdf" ;/* обработка шаблона и получение результрующего файла */$tpl -> define (array("svg" => «template.svg» ));
$tpl -> assign (array("USER_NAME" => $user_name ,
"R_DATE" => $register_date
));
$tpl -> parse ("SVG" , "svg" );//сохраням полученный svg файл
$tpl -> FastWrite ("SVG" , $tmp_svg_file );//производим конвертацию svg-файла средствами inkscape"а в ps-файл
//Ключи
// -T - служит для преобразования текста в кривые (для нормальной поддержки шрифтов)
// -P - указывает на необходимость преобразования в PostScript-файл
system («inkscape -T $tmp_svg_file -P $tmp_ps_file» , $success );if($success != 0 )
throw new Exception («Ошибка формирования ps-файла.» );//преобразуем ps-файл в pdf с помощью утилиты ps2pdf

//Ключи
// -dUseFlateCompression=true - устанавливает использование компрессии
// -dPDFSETTINGS=/printer - устанавливает оптимизацию для печати

system («ps2pdf -dUseFlateCompression=true -dPDFSETTINGS=/printer $tmp_ps_file $tmp_pdf_file» , $success );//в случае неудачного выполнения преобразования формируем исключение
if($success != 0 )
throw new Exception («Ошибка формирования pdf-файла.» );//заголовок о том, что будем оправлять pdf-файл
header ("Content-type: application/pdf" );// Называться будет как $pdf_file_name
header ("Content-Disposition: attachment; filename="" . $pdf_file_name . """ );// передаем сгенерированный файл
readfile ($tmp_pdf_file );//удаляем временные файлы
@ unlink ($tmp_svg );
@ unlink ($tmp_ps_file );
@ unlink ($tmp_pdf_file );catch (Exception $e ){
/* Если где-то произошла ошибка, то сообщаем об этом */
$tpl -> define (array("error" => «error.tpl» ));
$tpl -> assign ("ERROR" , $e -> getMessage ());$tpl -> parse ("ERROR" , "error" );
$tpl -> FastPrint ("ERROR" );
}
?>

Думаю, всем не составит особого труда переписать скрипт на другом языке программирования.

Онлайн или офлайн?

Создавайте файлы PDF из любого приложения. Работайте в режиме онлайн, используя наше онлайн-приложение, либо в режиме офлайн, загрузив настольное приложение Soda PDF на свой компьютер.

Создайте файл

Если вы решили создать файл PDF с помощью онлайн-приложения, загрузите имеющийся файл со своего компьютера или из облачного хранилища, такого как Google Drive или Dropbox.

Отправьте по почте

Когда файл PDF будет создан, вы можете отправить его на свой адрес электронной почты или загрузить на свой компьютер и просмотреть его в своем браузере.

ЗНАЕТЕ ЛИ ВЫ?

Есть новый, экологичный способ печати документов!

Нет необходимости использовать бумагу, когда вы можете использовать виртуальную печать. Когда вы загрузите приложение Soda PDF для настольного ПК, оно установит виртуальный принтер Soda PDF на ваш компьютер. Затем вы можете выбрать принтер Soda PDF из любой программы, чтобы преобразовать любой документ в формат PDF, не открывая настольное приложение Soda PDF! Когда вы будете готовы напечатать свой документ, просто выберите принтер Soda PDF из меню принтеров, и тогда будет создана копия документа в формате PDF. С помощью Soda PDF можно создавать файлы PDF из файлов более чем 300 форматов.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ О СОЗДАНИИ PDF

Формат PDF

Формат PDF был создан компанией Adobe Systems в 1993 году. В 2008 году он был стандартизован в качестве открытого формата, развитием которого стал заниматься независимый комитет ISO.

PDF 2.0

Формат PDF значительно эволюционировал с момента своего создания. Самой последней версией является версия PDF 2.0, стандарт которой был опубликован 28 июля 2017 г.

Другие возможности

Если вы хотите создать файл PDF путем объединения нескольких файлов, используйте наш бесплатный онлайн-инструмент "Объединить PDF". Вы даже можете выбрать порядок следования отдельных файлов в общем файле.







2024 © gtavrl.ru.