DOMPDF - export data from PHP to PDF

  • Tutorial
Using the DOMPDF library, you can create PDF files from HTML code. You just need to make up some HTML template and pass it to DOMPDF and get the generated PDF file at the output. But we must not forget that this library is not an engine for processing web pages, which means that templates should be made using the most basic means: HTML tags and CSS styles. Although the developers claim that their library supports CSS 2.1 standards and even some CSS 3 properties. A complete list of them can be found here.. There is, by the way, one minus - it is pretty “gluttonous” to RAM. Therefore, you may have to think about renting a virtual dedicated server. But it depends on the content and volume of the planned PDF documents. On the other hand, it can help you save a lot of time developing various reports in PDF format.
Reading various documentation on DOMPDF, and its a little and that basically more information in the form of answers to the asked questions. I noticed that it is used for more trivial tasks. Well, for example, the answer to the question: how to set the start page number for a document? I have not received.
Now I want to tell you about those "pitfalls" that I had to face. And believe me, I lost a lot of time. I would have lost even more if one kind person had not given me a couple of tips. Already experienced in working with this library.
I present a list of problems that I had to face:

  • lack of necessary directories with files (incomplete assembly);
  • partially working version of the library;
  • the presence of a bug when trying to set the document page number (start page number);
  • presence at the end of the document a blank page;
  • incomplete filling of the page with text (sometimes there was a lot of empty space).

As can be seen from all of the above, in this library there are enough unpleasant bugs, but if you try, you can "negotiate" with it.

Library installation


We take the library here . Unfortunately, I can’t say (as they usually say in such cases) that it is necessary to download the latest version. Next I will explain why. But I still hope that over time the bugs existing in the latest version will be fixed. After receiving the archive with the library, unzip it in the directory you need on the server.
In the root directory of the DOMPDF library there is a configuration file - dompdf_config.inc.php . It contains the basic settings of the library. We are interested in the following three:

  • the value of the DOMPDF_DEFAULT_PAPER_SIZE directive contains the value of the sheet size of the paper (a4, letter, etc.);
  • in the directive DOMPDF_DPI in numerical terms the quality of detail of the document is indicated. By default, it is 96;
  • the value of the DOMPDF_TEMP_DIR directive should be changed to the value contained in the PHP upload_tmp_dir directive , but only if the value returned by the PHP sys_get_temp_dir function is different from the value of this PHP directive. A complete list of possible settings can be found here .

The minimum server configuration should be as follows:

  • PHP Version 5.0;
  • DOMDocument extension;
  • PCRE
  • Zlib;
  • MBString extension;
  • Gd.

It is also recommended to install the GMagick or IMagick program and, accordingly, connect it through the extension to PHP. This feature is traced here: that supposedly installing one of the recommended programs will allow you to work better with the transparency of PNG images. But in practice, it turned out the following: if none of the programs are installed on the server, then the transparency of PNG images is not processed at all. The exception was for Denwera 3. For PHP 5.3, the Denwera 3 package included in the package did not need to be installed in either of these programs.

Install fonts


Initially, the library has a set of basic fonts, but among them there are no ones that support the Cyrillic alphabet. Therefore, if you need Cyrillic fonts or there is a need to expand the existing set of ready-made fonts, you will have to deal with their installation. And there is nothing complicated. You can install fonts as TrueType (* .ttf) and OpenType (* .otf). To work, we need the PHP script load_font.php , which is located in the root of the DOMPDF library directory. The launch of this script must be done from the command line and it accepts the following parameters as an input:

  • font_family - the name of the font;
  • n_file - file * .ttf or * .otf;
  • {b | i | bi} _file - files matching font styles (bold, italic, bold-italic).

Examples:

./load_font.php slkscr /usr/share/fonts/truetype/slkscr.ttf
./load_font.php Arial /mnt/c_drive/WINDOWS/Fonts/arial.ttf

To demonstrate, we will install the “roboto” font. Assume that the directory with the “roboto” font and its styles is located in the “D: \ font” directory. Accordingly, if we need only a font with the “normal” style, then we need to run the script with the following parameters:

./load_font.php Roboto D: \ font \ Roboto-Regular.ttf.

But if you want to install the “roboto” font with all four of its styles (normal, bold, italic and bold-italic), then the script call will already have a different look:

./load_font.php Roboto D: \ font \ Roboto-Regular.ttf D: \ font \ Roboto-Bold.ttf 
D: \ font \ Roboto-Italic.ttf D: \ font \ Roboto-BoldItalic.ttf.

Pay attention to the order of passing parameters to the script to simultaneously create the “roboto” font with its four styles. The path to the font file with the “normal” style is passed first, then “bold”, etc. Under no circumstances should this order be violated.

Creating a template for DOMPDF


The template represents a regular HTML page with the addition of some new CSS properties that are necessary for the library itself. I will not give the entire source code of the template here, since this is not necessary. Moreover, all the necessary files are attached to the article. By the way, you can embed PHP and JavaScript code in templates. In our case, the template will have six labels: the label for the set page number {start-page} , the label with the color code {color} for the footer of the page, the label {page-1} for the text on the first page, the label {page-2} for text on the second page and two labels {label-1} and {label-2}to display informational text in the basement. There will also be a built-in script in PHP for primitive drawing and output page numbering. Data that may occupy more than one page must be enclosed in a block. You can certainly not do this, but then there will be no way to insert page breaks, and the text may not evenly fill the page. To insert a page break, you should specify one of the following properties in the styles of this block:

  • page-break-after : always - inserts a gap after the page;
  • page-break-before : always - inserts a gap before the page;
  • page-break-inside : auto - here it means that DOMPDF itself will “make” a decision;
  • page-break-inside : avoid - Prevents a break inside an element.

Now it remains to do the pagination. To do this, write a small PHP script and paste it into the template.

if ( isset($pdf) ) {
	/*
	* Открытие объекта для сохранения всех
	* операций рисования
	*/
	$footer = $pdf->open_object();
	// Получаем ширину страницы
	$p_width = $pdf->get_width();
	// Получаем высоту страницы
    $p_height = $pdf->get_height();
	// Устанавливаем номер страницы
	$pdf->set_page_number({start-page});
	$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, "{PAGE_NUM}", $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");
}

Numbering can be done in another way. Create CSS style:
footer .page: after { 
    content: counter (page); 
}

And then in the place you need in the HTML code, insert the structure:


But only in the second option, you can not set the start page number. We may need to not start numbering from one, but for example from two, etc. In this case, only the use of the first method is suitable.

Note : When working with graphics in embedded scripts, the color value of each of the RGB components should be in the range 0 - 1. That is, each RGB color component needs to be divided by 255.

Creating a module for exporting data


The simplest thing left is to export the data. But there is another small bug in the library. It consists in the fact that if we need to generate several files, then for each iteration we need to create an instance of an object of the DOMPDF class again, otherwise you will receive an error message. Below is the source code of the module:
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('{' . $key . '}', $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);


The result should be a PDF file of the following sample:


conclusions


Although this library has quite a few flaws, it’s worth it. Firstly, it is free and this should already close all claims against the developers. Secondly, I think that in the near future, if not all, then many bugs will be fixed. The only problem is that, as I wrote above, that this library is used more for trivial tasks, so there is little description for solving various problems that arise.
All used files: PDF, template and export module can be downloaded from here .

Also popular now: