- doctor Brain
- Установка HTML2PDF
- Интеграция HTML2PDF в проект
- Преобразование HTML в PDF
- Вывод PDF-документа в браузер
- Заключение
- Новые публикации
- JavaScript: сохраняем страницу в pdf
- HTML: Полезные примеры
- CSS: Ускоряем загрузку страницы
- JavaScript: 5 странностей
- JavaScript: конструктор сортировщиков
- Категории
- О нас
- DOMPDF – экспорт данных из PHP в PDF
- Установка библиотеки
- Установка шрифтов
- Создание шаблона для DOMPDF
- Создание модуля для экспорта данных
- Выводы
doctor Brain
Итак, нам нужно получить файл в формате PDF из HTML-документа, стилизованного с помощью CSS. К сожалению, PHP не имеет встроенных функций, позволяющих выполнить такую задачу. Поэтому мы воспользуемся помощью библиотеки, созданной сторонними разработчиками.
Я полагаю, что конвертер html2pdf является отличным выбором, так как данная библиотека бесплатна и не имеет ограничений, связанных с ее распространением и модификацией даже в случае коммерческого использования. Несомненно, приятным моментом является то, что html2pdf не только преобразует HTML-синтаксис в PDF-формат, но и учитывает используемые для элементов конвертируемой страницы свойства CSS.
Также, следует отметить, что html2pdf работает с широким диапазоном версий PHP: от 5.6 до 7.4. Этот факт указывает на целесообразность использования данного конвертера для достаточно старых проектов.
Установка HTML2PDF
Конвертор html2pdf можно забрать из репозитария на github или установить с помощью Composer’а. В нашем примере мы используем последний вариант:
composer require spipu/html2pdf
Интеграция HTML2PDF в проект
Следующим шагом необходимо подключить конвертер к существующему проекту:
use Spipu\Html2Pdf\Html2Pdf;
Преобразование HTML в PDF
Для того, чтобы получить PDF-документ и вывести его в окно браузера можно использовать следующий код:
$html2pdf = new Html2Pdf(); $html2pdf->writeHTML('Title
Convert this HTML to PDF please!
'); $html2pdf->output('myPdf.pdf'); // Создаем PDF-документ и выводим его в браузер
Для того, чтобы создать PDF-документ и сразу перейти к его загрузке для функции output нужно установить второй аргумент D :
$html2pdf = new Html2Pdf(); $html2pdf->writeHTML('Title
Convert this HTML to PDF please!
'); $html2pdf->output('myPdf.pdf', 'D'); // Создаем PDF-документ и сразу его загружаем
Вывод PDF-документа в браузер
Можно заметить, что по умолчанию функция output создает PDF-документ и выводит его в окно браузера. В результате, можно не только просмотреть в окне браузера, но и скачать преобразованный в PDF-формат файл.
Заключение
html2pdf далеко не единственная библиотека, позволяющая конвертировать HTML-документ в формат PDF. Тем не менее, она проста в использовании, имеет хорошее описание и не требует дополнительных затрат.
Новые публикации
JavaScript: сохраняем страницу в pdf
HTML: Полезные примеры
CSS: Ускоряем загрузку страницы
JavaScript: 5 странностей
JavaScript: конструктор сортировщиков
Категории
О нас
Frontend & Backend. Статьи, обзоры, заметки, код, уроки.
© 2021 dr.Brain .
мир глазами веб-разработчика
DOMPDF – экспорт данных из PHP в PDF
С помощью библиотеки DOMPDF можно создавать PDF файлы из HTML кода. Нужно только сверстать некий HTML шаблон и передать его DOMPDF и уже на выходе получить сгенерированный PDF файл. Но не надо забывать и то, что эта библиотека не движок для обработки веб-страниц, а значит и шаблоны должны быть сверстаны с использованием самых базовых средств: HTML тегов и CSS стилей. Хотя разработчики заявляют, что их библиотека поддерживает стандарты CSS 2.1 и даже некоторые свойства CSS 3. С полным их перечнем можно ознакомиться здесь. Есть, кстати, один минус – она является довольно “прожорливой” к оперативной памяти. Поэтому возможно придется задуматься об аренде виртуального выделенного сервера. Но это зависит от содержания и объема планируемых PDF документов. С другой стороны она вам может помочь сэкономить много времени на разработку различных отчетов в формате PDF.
Читая различную документацию по DOMPDF, а ее немного и то в основном больше информации в виде ответов на заданные вопросы. Я заметил, что ее используют для более тривиальных задач. Ну, к примеру, ответа на вопрос: как задать номер стартовой страницы для документа? Мной получено не было.
Сейчас я вам хочу рассказать о тех “подводных камнях”, с которыми мне пришлось столкнуться. И поверьте, я потерял много времени. Потерял бы еще больше, если бы мне не дал пару советов один добрый человек. Уже имевший опыт по работе с данной библиотекой.
Представляю перечень проблем, с которыми мне пришлось столкнуться:
- отсутствие необходимых каталогов с файлами (не полная сборка);
- частично рабочая версия библиотеки;
- наличие бага при попытке установки номера страницы документа (номер стартовой страницы);
- наличие в конце документа пустой страницы;
- не полное заполнение страницы текстом (иногда оставалось много пустого места).
Установка библиотеки
Саму библиотеку берем вот здесь. Я, к сожалению, не могу сказать (как обычно говорят в таких случаях), что необходимо скачать самую новую версию. Далее я объясню почему. Но я все-таки надеюсь, что со временем существующие в последней версии баги будут устранены. После получения архива с библиотекой, распакуйте его в нужную вам на сервере директорию.
В корневом каталоге библиотеки DOMPDF находиться файл конфигурации – dompdf_config.inc.php. В нем присутствуют базовые настройки библиотеки. Нас здесь интересуют следующие три:
- значением директивы DOMPDF_DEFAULT_PAPER_SIZE содержит значение размера листа бумаги (a4, letter и т.д.);
- в директиве DOMPDF_DPI в численном выражении указывается качество детализации документа. По умолчанию оно равно 96;
- значение директивы DOMPDF_TEMP_DIR следует изменить на содержащееся значение в PHP директиве upload_tmp_dir, но только в том случае, если значение, возвращенное PHP функцией sys_get_temp_dir, будет отличным от значения этой PHP директивы. С полным перечнем возможных настроек можно ознакомиться здесь.
- PHP Version 5.0;
- DOMDocument extension;
- PCRE;
- Zlib;
- MBString extension;
- GD.
Установка шрифтов
Изначально в библиотеке присутствует набор базовых шрифтов, однако среди них нет тех, которые поддерживали бы кириллицу. Поэтому если нужны кириллические шрифты или есть необходимость в расширении имеющегося множества уже готовых шрифтов, то придется заняться их установкой. И в этом нет ничего сложного. Устанавливать можно шрифты как TrueType (*.ttf) так и OpenType (*.otf). Для работы нам понадобится PHP скрипт load_font.php, который располагается в корне каталога библиотеки DOMPDF. Запуск данного скрипта необходимо производить из командной строки и на вход он принимает следующие параметры:
- font_family – имя шрифта;
- n_file – файл *.ttf или *.otf;
- _file – файлы соответствующие стилям шрифта (bold, italic, bold-italic).
./load_font.php slkscr /usr/share/fonts/truetype/slkscr.ttf ./load_font.php Arial /mnt/c_drive/WINDOWS/Fonts/arial.ttf
Для демонстрации произведем установку шрифта “roboto”. Предположим что каталог со шрифтом “roboto” и его стилями находится в директории “D:\font”. Соответственно если нам нужен только шрифт со стилем “normal”, то необходимо запустить скрипт со следующими параметрами:
./load_font.php Roboto D:\font\Roboto-Regular.ttf.
Но если требуется установить шрифт “roboto” со всеми четырьмя его стилями (normal, bold, italic и bold-italic), то вызов скрипта уже будет иметь другой вид:
./load_font.php Roboto D:\font\Roboto-Regular.ttf D:\font\Roboto-Bold.ttf D:\font\Roboto-Italic.ttf D:\font\Roboto-BoldItalic.ttf.
Обратите внимание на порядок передачи параметров скрипту для одновременного создания шрифта “roboto” с его четырьмя стилями. Первым передается путь к файлу шрифта со стилем “normal”, затем “bold” и т.д. Этот порядок нарушать ни в коем случае нельзя.
Создание шаблона для DOMPDF
Шаблон представляет обычную HTML страницу с добавлением некоторых новых свойств CSS, которые необходимы для работы самой библиотеки. Весь исходный код шаблона я здесь приводить не стану, так как в этом нет необходимости. Тем более что к статье прилагаются все необходимые файлы. Кстати в шаблоны можно встраивать код на PHP и JavaScript. В нашем случае в шаблоне будет располагаться шесть меток: метка для устанавливаемого номера страницы , метка с кодом цвета для подвала страницы, метка для текста на первой странице, метка для текста на второй странице и две метки и для вывода информационного текста в подвал. Также будет присутствовать встроенный скрипт на PHP для примитивного рисования и вывода нумерации страниц. Данные, которые могут занимать более одной страницы необходимо заключать в блок. Можно конечно этого не делать, но тогда не будет возможности вставлять разрывы страниц, да и текст может не равномерно заполнять страницу. Для вставки разрыва страницы, следует в стилях этого блока прописать одно из следующих свойств:
- page-break-after: always – вставляет разрыв после страницы;
- page-break-before: always – вставляет разрыв перед страницей;
- page-break-inside: auto – здесь имеется ввиду, что DOMPDF сама “примет” решение;
- page-break-inside: avoid – запрещает разрыв внутри элемента.
if ( isset($pdf) ) < /* * Открытие объекта для сохранения всех * операций рисования */ $footer = $pdf->open_object(); // Получаем ширину страницы $p_width = $pdf->get_width(); // Получаем высоту страницы $p_height = $pdf->get_height(); // Устанавливаем номер страницы $pdf->set_page_number(); $font = Font_Metrics::get_font("Roboto", "normal"); //$text_w = $pdf->get_text_width($PAGE_NUM, "Roboto", 14); /* * Сами (для примера) рассчитываем ширину текста (номера страницы) * иначе есть видимо неустранимый пока баг */ $text_w = 8.036; // Получаем высоту текста (номера страницы) $text_h = $pdf->get_font_height("Roboto", 14); $x = $p_width - $text_w - 15; $y = $p_height - $text_h / 2 - 20; // Выводим текст на страницу $pdf->page_text($x, $y, "", $font, 14, array(255, 255, 255)); // Рисуем окружность $radius = min($text_w * 1.5, $text_h * 1.5); $color = array(0, 0.607, 0.901); $pdf->circle($x + $text_w / 2, $y + $text_h / 2, $radius, $color); // закрытие текущего объекта $pdf->close_object(); /* * Добавляет объект на каждую страницу * также можно добавлять на четную или нечетную: "even" или "odd") */ $pdf->add_object($footer, "all"); >
Но только во втором варианте, нельзя задать номер стартовой страницы. Возможно, нам понадобиться не начинать нумерацию с единицы, а к примеру с двойки и т.д. В таком случае подойдет только использование первого метода.
Примечание: При работе с графикой во встроенных скриптах, значение цвета каждой из RGB составляющих должно находиться в диапазоне 0 — 1. Т.е. каждую составляющую цвета в формате RGB требуется разделить на 255.
Создание модуля для экспорта данных
Осталось самое простое – это сделать экспорт данных. Но есть в библиотеке и еще один небольшой баг. Он заключается в том, что если нам понадобиться сгенерировать несколько файлов, то нужно для каждой итерации создавать экземпляр объекта класса DOMPDF заново, иначе вы получите сообщение об ошибке. Ниже приведен исходный код модуля:
define ( 'ROOT_DIR', dirname ( __FILE__ ) ); define ( 'BASE_PATH', ROOT_DIR . '/template/icon'); define ( 'TEMPLATE', ROOT_DIR . '/template/main.html' ); // Подключаем файл с конфигурацией DOMPDF require_once (ROOT_DIR . '/dompdf/dompdf_config.inc.php'); // Загрузка шаблона if (@file_exists(TEMPLATE) ) $template = file_get_contents(TEMPLATE); /* * Номер текущей страницы * если требуется сгенерировать несколько документов */ $current_page = 1; // Массив с метками и их значениями для шаблона $signs = array ( 'color' => '#0080C0', 'page-1' => 'Страница 1', 'page-2' => 'Страница 2', 'label-1' => 'site.com', 'label-2' => 'info@site.com', 'start-page' => $current_page); // Замена меток в шаблоне их значениями foreach ($signs as $key => $value) $template = str_replace('', $value, $template); $pdf = new DOMPDF(); // Устанавливаем путь к директории с изображениями и CSS стилями $pdf->set_base_path(BASE_PATH); // Загружаем шаблон $pdf->load_html($template); // Генерируем PDF файл $pdf->render(); // Получаем данные в формате PDF $data = $pdf->output(); /* * Увеличили счетчик числа сгенерированных страниц * на число страниц текущего документа */ $current_page = $current_page + $pdf->get_canvas()->get_page_count(); // Сохраняем PDF файл file_put_contents(ROOT_DIR . "/example.pdf", $data);
В результате должен получиться PDF файл следующего образца:
Выводы
Хотя в данной библиотеке и достаточно различных недоработок, но она того стоит. Во-первых, она бесплатная и это уже должно закрыть все претензии к разработчикам. Во-вторых, я думаю, что в ближайшее время если не все, то многие баги будут устранены. Единственная проблема в том, что как я уже писал выше, что данная библиотека используется больше для тривиальных задач, поэтому мало есть описания для решения различных возникающих проблем.
Все используемые файлы: PDF, шаблон и модуль экспорта можно скачать отсюда.