DOMPDF es un conversor de HTML a PDF escrito en PHP. Interpreta HTML y CSS para la generación de documentos en PDF con un soporte bastante adecuado para CSS 2.1, incluso algunos avanzados como bordes redondeados en las cajas. En este post presentaré algunas peculiaridades de esta librería que espero ayuden a sacar partido de la versatilidad del HTML para generar documentos en PDF.
Parece que mucha gente se olvida que HTML permite trabajar en muchos soportes distintos, no solo en display, sino también en impresora. Hoy en día documentación como albaranes de compra en comercio electrónico se generan online para enviar al comprador. Haremos uso de esta característica de HTML para componer HTML ajustado a soporte papel que será el que utilizaremos para generar PDFs.
DONDE OBTENER LA LIBRERÍA E INSTALACIÓN
Podeís obtener la versión más actualizada en GitHub y tiene una buena documentación y ejemplos en inglés de uso. Como veis no es especialmente exigente en sus requerimientos:
- PHP 5.3+ (recomendado)
- DOM extension
- GD extension
Siguiendo las instrucciones es sencilla su instalación en cualquier proyecto.
<?php // Cargamos la librería dompdf que hemos instalado en la carpeta dompdf require_once ('dompdf/dompdf_config.inc.php'); // Introducimos HTML de prueba $html = '<h1>Hola mundo!</h1>'; // Instanciamos un objeto de la clase DOMPDF. $pdf = new DOMPDF(); // Definimos el tamaño y orientación del papel que queremos. $pdf->set_paper("A4", "portrait"); // Cargamos el contenido HTML. $pdf->load_html(utf8_decode($html)); // Renderizamos el documento PDF. $pdf->render(); // Enviamos el fichero PDF al navegador. $pdf->stream('FicheroEjemplo.pdf'); |
PECULIARIDADES A TENER EN CUENTA
Aunque facilita mucho la generación de los documentos es importante tener en cuenta algunos aspectos en lo tocante al HTML y la codificación:
- Utiliza siempre UTF8. Aunque ya deberías de saberlo y deberías de utilizarlo siempre como charset por defecto en Bases de datos, codificación de ficheros, etc no está de más recordarlo. DOMPDF utiliza por defecto este charset y no le sienta nada bien la mezcla. Te puedes encontrar con que no muestra el volcado de datos que te interesa simplemente porque se encuentra un carácter en una codificación inadecuada.
- Tamaño del papel y orientación. Por supuesto puedes elegir el tamaño de papel que desees. La clase que incluye los tamaños de papel y sus dimensiones se encuentra en include/cpdf_adapter.cls. Si necesitas utilizar un tamaño de papel personalizado utiliza la siguiente sintaxis con las dimensiones que necesitas:
$paper_size = array(0,0,360,360); $dompdf->set_paper($paper_size);
- El fichero de configuración. Es el fichero que utilizamos en el include, como verás se encuentra bien documentado, por defecto dompdf_config.inc.php
LA GENERACIÓN DEL HTML
Unos breves consejos a la hora de preparar nuestro HTML para generar el PDF:
UTILIZA TABLAS EN LA MAQUETACIÓN
Efectivamente. Aquello que no nos cansamos siempre de decir: las tablas se deben de utilizar para mostrar datos tabulares, no para maquetar o diseñar. Olvídate. El soporte que tiene de la propiedad CSS float: es bastante limitada así que para simplificar es mejor utilizar tablas como si estuvieras preparando el HTML de una campaña por email.
NADA DE HTML5
Aunque tiene cierto soporte HTML5 tampoco tiene mucho sentido de cara a la generación de ficheros PDF, así que si estás generando el HTML de cero puedes ahorrártelo.
UTILIZACIÓN DE IMÁGENES EN PNG Y JPG
La renderización de imágenes es perfecta, utilizando cada tipo de fichero para lo que es. Puedes utilizar PNG para logotipos aprovechando que puede manejar canal alpha y transparencia; y los JPG para fotografías.
PIENSA EN PAPEL
Aunque es obvio a veces se nos olvida que el soporte al que va destinado nuestro HTML es papel. Por este motivo (y más sin contamos con una plantilla de documento) debemos de utilizar medidas basadas en mm en todo lo relativo a márgenes de documento, en tablas, etc.
Lo mismo se aplica a los tipos de letra. Recuerda que la unidad a utilizar son los .pt (puntos). Si cuentas con un documento de texto (.doc, .odt, etc) en el que basarte aún mejor, tendrás toda esa información en el acto consultando las propiedades del documento o colocando el ratón sobre los tipos de letra para conocer su propiedades.
Si no cuentas con una plantilla digital consigue una regla de diseño gráfico que mida tanto en mm como en pt.
MÁRGENES A CERO
Por defecto a la hora de preparar el HTML te aconsejo que situes los márgenes a 0 y sea en el body donde definas los márgenes.
html { margin: 0; } body { font-family: "Times New Roman", serif; margin: 45mm 8mm 2mm 8mm; } |
SALTOS DE PÁGINA MANUALES
Los saltos de página como cualquier editor DOMPDF los realiza de forma auomática, pero podemos forzar que la aparición de un elemento en HTML provoque el salto de linea. Yo generalmente utilizo el tag <hr> con las siguientes propiedades CSS:
hr { page-break-after: always; border: 0; margin: 0; padding: 0; } |
INCLUIR CABECERAS Y PIES DE PÁGINA FIJOS
DOMPDF hace un uso bastante inteligente de la propiedad position: de CSS. Cualquier elemento situado con fixed se repetirá a lo largo de todas las páginas del documento. Lo cual hace que sea una propiedad muy útil para incluir logos de empresa, direcciones, datos de contacto, etc.
Si por contra utilizamos position: absolute su comportamiento será el habitual, pudiendo situar un elemento en cualquier posición de la página con las propiedades top: y left:. Pero sólo en la página actual.
INCLUIR NÚMEROS DE PÁGINA
DOMPDF permite ejecutar código PHP embebido. Tienes más información en la documentación oficial, pero uno muy importante es el relativo a la paginación. En cualquier documento poder incluir el número de páginas es fundamental y para ello podemos utilizar el siguiente código que nos incluirá la paginación en el punto que le indiquemos:
<script type="text/php"> if (isset($pdf)) { $font = Font_Metrics::get_font("Arial", "bold"); $pdf->page_text(765, 550, "Pagina {PAGE_NUM} de {PAGE_COUNT}", $font, 9, array(0, 0, 0)); } </script> |
IMPORTANTE: Recuerda activar en la configuración de DOMPDF DOMPDF_ENABLE_PHP = true
o de lo contrario no ejecutará el código y no veremos la paginación.
EMPLEO DE BUFFERS Y $_SESSION
Cuando quieras generar algún tipo de documento complejo en HTML comprobarás que ciertos modos de generarlo en PHP no son válidos, sobre todo en aquellos en el que vas generando el HTML dentro de un buffer para volcar luego todo el contenido en una variable en PHP. Por algún motivo no suele funcionar de forma directa. Y por otro lado ir concatenando cadenas y cadenas de HTML al final es bastante aburrido.
Por ese motivo lo que suelo hacer es grabar el contenido HTML por medio de buffers, almacenar la información en una variable de sessión; y en un controlador aparte recuperar el contenido de la variable de sessión con el HTML para que lo genere DOMPDF. Por ejemplo:
<?php session_start(); // Iniciamos el buffer ob_start(); // Operaciones para generar el HTML que pueden ser llamadas a Bases de Datos, while, etc... require_once ('plantilla.html'); (...) // Volcamos el contenido del buffer $html = ob_get_clean(); // Creamos la variable de sesión $_SESSION['pdf']['content'] = $html; $_SESSION['pdf']['filename'] = 'Informe.pdf'; $printpdf = true; |
Desde aquí procedemos a la carga del controlador que ejecuta el siguiente código si encuentra $printpdf = true; en otro punto de la ejecución.
<?php session_start(); // DOMPDF según el tipo de documento a imprimir o la cantidad puede ser muy exigente así que aumentamos la memoria disponible ini_set("memory_limit", "128M"); // Cargamos DOMPDF require_once 'dompdf/dompdf_config.inc.php'; // Recuperamos la información de la sesión $html = $_SESSION['pdf']['content']; $filename = $_SESSION['pdf']['filename']; // Volcamos las páginas en papel $dompdf = new DOMPDF(); $dompdf->set_paper('A4', 'landscape'); // Se carga el codigo html $dompdf->load_html($html); // Lanzamos a render $dompdf->render(); // Guardamos a PDF $dompdf->stream($filename); // Borramos la variable de sesión unset($_SESSION['pdf']); |
Eso es todo. Espero que os sea de utilidad.
FUENTES
Página oficial de DOMPDF
Generación de PDF’s con PHP y la librería DOMPDF
De Manuais Informática – IES San Clemente.
Personalizar el tamaño de página en DOMPDF
Para pasar las imagenes a los pdf hay que hacerlo en base64
DOMPDF
Libreria para php7
Compatiblidades de la libreria
ALGORITMO EN PHP PARA GENERAR IMAGENES EN BASE64.
Si teneis que volcar imagenes en la libreria dompdf, es necesario pasarlas a base64. A continuación os dejo un ejemplo de función para conseguir tal propósito.
* This loads in the file, image.jpg for manipulation.
* The filename path is releative to the .php file containing this code, so
* in this example, image.jpg should live in the same directory as our script.
*/
$imge = new Imagick($img);
/**
* This resizes the image, to the given size in the form of width, height.
* If you want to change the resolution of the image, rather than the size
* then $img->resampleimage(320, 240) would be the right function to use.
*
* Note that for the second parameter, you can set it to 0 to maintain the
* aspect ratio of the original image.
*/
$imge->resizeImage(640, 470,1,1);
/**
* This returns the unencoded string representation of the image
*/
$imgBuff = $imge->getimageblob();
/**
* This clears the image.jpg resource from our $img object and destroys the
* object. Thus, freeing the system resources allocated for doing our image
* manipulation.
*/
$imge->clear();
/**
* This creates the base64 encoded version of our unencoded string from
* earlier. It is then output as an image to the page.
*
* Note, that in the src attribute, the image/jpeg part may change based on
* the image type you’re using (i.e. png, jpg etc).
*/
$imge = base64_encode($imgBuff);
return $imge;
}
ImgBase64($img);
/* img es la ruta absoluta donde tengaias las imagens y el nombre del fichero */
?>