Creacion de archivos PDF en PHP con DOMPDF
18.07.07Muchas veces cuando mostramos información por pantalla como cotizaciones, informes, documentos, etc. nos gustaría que nuestros clientes y/o usuarios tuvieran el resultado en archivos sean WORD, EXCEL O PDF.
PDF es nuestro caso es el archivo que nos interesa puesto que es uno de los formatos más utilizados ya que la información contenida en ella no se puede alterar, para crear dichos archivos y buscando un poco por la web y con ayuda de san google he encontrado una herramienta que nos servirá mucho en la solución de este problema entre las muchas que hay pero con diferencia que DOMPDF provee soporte para la creación de archivos PDF sobre archivos html con estilos(css) pero no todas las propiedades, no acepta posiciones flotantes ni relativas entre otras, para saber que propiedades son aceptadas y cuales no revisa en siguiente link
Bueno empecemos, primero lo primero nos bajamos la ultima versión del DOMPDF,que ahora se encuentra en la versión 0.5.1 para utilizarlo requerimos de php 5 o superior con la extensión DOM habilitada.
Una vez descargado el paquete procedemos a descomprimirlo en nuestra carpeta web y nos centramos en el archivo dompdf_config_inc.php, este archivo contiene todas las especificaciones básicas con las cuales se creará el archivo PDF se recomienda dejar tal como esta a continuación detallo las más importantes
define("DOMPDF_DIR", realpath(dirname(__FILE__)));
/*El directorio donde se encuentra DOMPDF */
define("DOMPDF_INC_DIR", DOMPDF_DIR . "/include");
/* Directorio de los archivos Inc */
define("DOMPDF_LIB_DIR", DOMPDF_DIR . "/lib");
/* Directorio de las Librerías */
define("DOMPDF_FONT_DIR", DOMPDF_DIR . "/lib/fonts/");
/* Directorio donde se encuentran los Tipos de Letras(fuentes)*/
/*con las que se creara el archivo, mas adelante insertaremos*/
/*nuestras propias fuentes al PDF */
define("DOMPDF_ENABLE_PHP", true);
/* Esta opción permite crear */
/*archivos PDF a través de paginas PHP */
Bueno luego de visto el archivo de configuración procedemos a crear nuestro primer script PHP
PDF desde una Url Html
<?php
/* Incluimos el archivo de configuracion */
require_once("dompdf/dompdf_config.inc.php");
/* creamos un nuevo objeto */
$dompdf = new DOMPDF();
/* Llamamos a nuestro archivo html */
/* a través del método "load_html_file" */
$dompdf->load_html_file("http://www.inventa-design.com/
blog/wp-content/uploads/2007/07/prueba.html");
$dompdf->render();
$dompdf->stream("prueba.pdf");
?>
Al ejecutar el archivos nos aparecerá una ventana para descargar el archivo PDF, nos podemos dar cuenta lo fácil que es crear el archivo y que se muestra con los estilos indicados
PDF desde Codigo Html
<?php
/* Incluimos el archivo de configuracion */
require_once("dompdf/dompdf_config.inc.php");
$html = '<html><head>
<title>Prueba 2</title>
<style type="text/css">
body{
margin: 15px 40px;
}
table th{
background-color:#333333;
color:#CCCCCC;
}
table{
border-collapse:collapse;
border:#c0c0c0 solid 1px;
}
table td{
text-align:center;
}
p{
text-align:justify;
}
h2{
color:#003366;
border-bottom:#003366 solid 3px;
}
</style>
</head>
<body><h2>Prueba 2</h2>
<br /><br />
<table border="0" align="center" >
<tr><th>header1</td><th>header 2 </td><th>header3</td></tr>
<tr><td>1</td><td>2</td><td>2</td></tr>
<tr><td>3</td><td>5</td><td>5</td></tr>
<tr><td>6</td><td>5</td><td>8</td></tr>
<tr><td>4</td><td>8</td><td>5</td></tr>
<tr><td>6</td><td>8</td><td>9</td></tr>
<tr><td>1</td><td>2</td><td>3</td></tr>
</table>
<br />
<p>Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Phasellus nec leo. Pellentesque
ac diam quis urna elementum dignissim.
Maecenas sit amet risus. Aliquam orci. Vivamus
lacinia mauris ac ipsum. Nullam sagittis odio non
mi. Praesent dictum arcu vel nisi. Praesent urna
dolor, aliquet ut, pulvinar nec, eleifend vel, nisi.
Sed eget odio imperdiet dolor aliquam cursus.
Ut facilisis auctor est. Nam dictum sagittis orci.
Praesent dapibus tempus dui. Donec aliquet,
risus at vulputate dictum, dui eros congue elit,
quis hendrerit elit purus et ligula. Curabitur
condimentum. Nunc semper dolor laoreet purus.
Fusce urna nunc, scelerisque eu, sagittis sit
amet, pellentesque malesuada, magna.
Vestibulum magna mauris, rutrum quis,
fringilla id, varius a, lectus.</p>
</body>
</html>
';
/*creamos un nuevo objeto */
$dompdf = new DOMPDF();
/*Con el método "load_html" cargamos nuestro código HTML */
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream("prueba.pdf");
?>
Ahora bien los ejemplos que he puesto nos crea archivos estáticos, es decir siempre serán los mismos ahora bien podemos crear dinamismo usando el modo anterior con lenguaje php y el resultado setearlo a la variable “$html”, otra opción es utilizar la función load_html_file ya que para nuestra suerte DOMPDF crea archivos también desde paginas PHP
Definiendo Margenes
Cuando abrimos o descargamos el archivo del ejemplo 1 te abras dado cuenta que el texto esta muy pegado a los bordes de la pagina que no ocurre en el ejemplo 2, la diferencia radica en que hemos utilizado estilos para definir margenes al documento.
body{
/* Margen de 20px a cada lado */
margin: 20px;
/* Margen de 15px arriba y abajo,
margen de 40px a los costados */
margin: 15px 40px;
/* Margenes Detallados*/
margin-top: 10px;
margin-left: 15px;
margin-right: 20px;
margin-bottom: 30px;
}
Creando Cabecera y Pie de Pagina
Ahora bien muchas veces necesitamos mostrar el logo de la compañía como cabecera y el contacto, dirección y/o ubicación como pie de pagina,no podemos hacerlo creando paneles flotantes o fijos pues DOMPDF no soporta ese tipo de estilos para ello usaremos el objeto “$pdf” que se crea en el momento de ejecución
<?php
/* Incluimos el archivo de configuracion */
require_once("dompdf/dompdf_config.inc.php");
$html = '<html><head>
<title>Prueba 2</title>
<style type="text/css">
body{
margin-top:120px;
margin-left:40px;
margin-right:40px;
margin-bottom:40px;
}
table th{
background-color:#333333;
color:#CCCCCC;
}
table{
border-collapse:collapse;
border:#c0c0c0 solid 1px;
}
table td{
text-align:center;
}
p{
text-align:justify;
}
h2{
color:#003366;
border-bottom:#003366 solid 3px;
}
</style>
</head>
<body>
<script type="text/php">
$header=$pdf->open_object();
$font = Font_Metrics::get_font("verdana", "bold");
$texto = "Google INC. 1600 Amphitheatre Parkway Mountain
View CA 94043";
$hpagina = $pdf->get_height();
$wpagina = $pdf->get_width();
$wtexto = Font_Metrics::get_text_width($texto, $font, 14);
$pdf->image("http://www.google.com.pe/intl/en_com/
images/logo_plain.png", "png", 40, 40, 200, 80);
$pdf->page_text($wpagina/2 - $wtexto/2, $hpagina-50, $texto,
$font, 14, array(0,0,0));
$pdf->page_text($wpagina/2 , $hpagina-35, "{PAGE_NUM}" ,
$font, 14, array(0,0,0));
$pdf->close_object();
$pdf->add_object($header, "all");
</script>
<h2>PDF con Header y Footer :</h2>
<br /><br />
<table border="0" align="center"
cellpadding="0" cellspacing="0">
<tr>
<th>header1</td>
<th>header 2 </td>
<th>header3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>5</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>5</td>
<td>8</td>
</tr>
<tr>
<td>4</td>
<td>8</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
<br />
<p>
<?php
for($a=1;$a<=50;$a++){
echo "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
In diam magna, tempus id, mattis at, nonummy";
}
?>
</p>
</body>
</html>';
/*creamos un nuevo objeto */
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream("prueba.pdf");
?>
Explicamos un poco el codigo
/* Aqui definimos los margenes de la pagina*/
/* Para que el texto no se cruce con la imagen */
/* de la cabecera ni con el pie de pagina */
body{
margin-top:120px;
margin-left:40px;
margin-right:40px;
margin-bottom:40px;
}
/*abrimos el objecto*/
$header=$pdf->open_object();
/* seleccionamos el tipo de fuente
ya instalada en DOMPDF */
$font = Font_Metrics::get_font("verdana", "bold");
/* Estas funciones nos recuperan
el ancho y altura de la pagina */
$hpagina = $pdf->get_height();
$wpagina = $pdf->get_width();
/* Esta función nos devuelve el ancho del texto de */
/* pie de pagina según su fuente y su tamaño */
$wtexto = Font_Metrics::get_text_width($texto, $font, 14);
/* El metodo "image" nos colocara una imagen en la pagina */
/* los parametros son la url, el tipo de imagen */
/* posicion x, posicion y, ancho y altura */
$pdf->image("http://www.google.com.pe/intl/en_com/
images/logo_plain.png", "png", 40, 40, 200, 80);
/* con "page_text" añadimos texto en la pagina */
/* para centrarlo restamos la mitad de ancho */
/* de la pagina menos la mitad del ancho del texto */
/* array(0,0,0) es el valor del color */
$pdf->page_text($wpagina/2 - $wtexto/2, $hpagina-50, $texto,
$font, 14, array(0,0,0));
/* PAGE_NUM nos devuelve el numero de pagina actual */
$pdf->page_text($wpagina/2 , $hpagina-35, "{PAGE_NUM}" ,
$font, 14, array(0,0,0));
/* cerramos el objecto */
$pdf->close_object();
/* añadimos lo anterior a todas la paginas */
$pdf->add_object($header, "all");
$pdf->page_text($wpagina/2 - $wtexto/2, $hpagina-50, $texto,
$font, 14, array(0,0,0));
Asi pues ya tenemos creado el pdf y listo para descargar pero si queremos que el archivo sea interno y se guarde en el servidor? pues bueno hacemos un pequeño cambio
/*Remplazamos esta linea */
$dompdf->stream("prueba.pdf");
/* Por estas */
$pdf = $dompdf->output();
/* definimos la path de destino */
file_put_contents("prueba_interna.pdf", $pdf);
Con todo esto ya esta completamente listo el poder crear archivos PDF dinámicos solo faltaría el poder darle un toque personal a nuestro PDF insertando nuestras propias fuentes para eso nos bajamos Ttf2Pt1 que convertira nuestra tipografia TrueType a Postscript type-1., para el próximo ejemplo he utilizado la tipografía Only When I Do Fonts
Una vez descargado e instalado el ttf2pt1 procedemos a ejecutarlo en modo de comando, ejecutamos la sentencia “ttf2pt1 -bA “c:\onlywif_.ttf” o “ttf2pt1 -bGA “c:\onlywif_.ttf” esto nos creara 2 archivos en la direccion donde se encuentra nuestra fuente en este ejemplo la unidad “c:”
Copiamos los archivos generados a la carpeta fonts de DOMPDF

Luego procedemos a abrir en la misma carpeta el archivo “dompdf_font_family_cache” y “dompdf_font_family_cache.dist” al abrirlo nos damos cuenta que contiene un grupo de arrays con los nombres de las fuentes que se encuentra actualmente y que a su ves esta contenido en un array general lo unico que haria falta es crear un arreglo con el nombre de nuestra fuente
'onlywif_' =>
array (
'normal' => DOMPDF_FONT_DIR . 'onlywif_',
'bold' => DOMPDF_FONT_DIR . 'onlywif_',
'italic' => DOMPDF_FONT_DIR . 'onlywif_',
'bold_italic' => DOMPDF_FONT_DIR . 'onlywif_',
)
Luego de añadido el arreglo en los dos archivos procedemos a probarlo con el siguiente ejemplo
<?php
/* Incluimos el archivo de configuracion */
require_once("dompdf/dompdf_config.inc.php");
$html = '<html><head>
<title>Prueba 2</title>
<style type="text/css">
body{
margin-top:120px;
margin-left:40px;
margin-right:40px;
margin-bottom:40px;
}
h1{
color:#003366;
border-bottom:#003366 solid 3px;
font-family:onlywif_;
}
p{
text-align:justify;
}
</style>
</head>
<body>
<h1>Probando Fuente</h1>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
In diam magna, tempus id, mattis at, nonummy</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
In diam magna, tempus id, mattis at, nonummy</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
In diam magna, tempus id, mattis at, nonummy</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
In diam magna, tempus id, mattis at, nonummy</p>
</body>
</html>';
/*creamos un nuevo objeto */
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream("prueba.pdf");
?>
Para utilizar la fuente hemos utilizado estilos la propiedad font-family y el nombre de la fuente
font-family:onlywif_;
Con todo esto ya podemos crear archivos PDF sin mucho problema así que si tienes consejos o preguntas házmelo saber a través de los comentarios.




23 Comentarios
10.09.07 :: 14:07
hola, una pregunta sobre tu tema, este dompdf lo tienes bajo linux o bajo windows ??? yo lo descarge pero no puedo hacerlo funcionar bajo windows, no logro darle la configuracion necesaria para que funcione
11.09.07 :: 19:27
Hola yo tampoco puedo hacerlo funcionar.. sera porque ha sido escrito en la version 5 de php? yo tengo php version 4.3.9 y no me corre..
si esto llega a funcionar seria genial, fantastico!
saludos y por favor, escribeme avisandome si tienes alguna solucion.
11.09.07 :: 23:43
Uno de los requerimientos de DOMPDF es que necesita tener php5 o superior ademas de contar con la opción de DOM habilitada, jorge no tiene nada que ver que este en windows o en linux pq al final es una aplicación web si tienes problemas fíjate si tu servidor apache con php este bien configurado ademas que este en la versión 5 o superior con la opción DOM habilitada
22.10.07 :: 5:36
Hola,
genial post sobre esta clase tan util.
Tengo un problemilla a ver si me podriais echar una mano:
cuando utilizo el “new_page()” y escribir, el texto no se coloca al comienzo de esta nueva pagina. Por que puede ser? no estoy utilizando CSS.
Gracias
30.10.07 :: 17:41
Me sirve hasta cierto punto, por ejemplo, cuando hago una tabla pequena sirve pero cuando ya le pongo mas filas se totea y me sale este error;
“Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 1572864 bytes) in C:\wamp\www\dompdf\lib\class.pdf.php(2219) : eval()’d code on line 5914″
Creo que debe tener un limite de caracteres? Como le aumento?
31.10.07 :: 10:39
hola, tengo un problema para crear el pdf con 2 op paginas osea el contenido esta bien pero solo aparece an una pagina y queiro que el contenido se distribuya en varias segun el tamaño que le nvio desde le html, como lo soluciono
03.11.07 :: 12:23
Primeramente gracias por sus comentarios y disculpen si contesto después de tiempo estoy muy ocupado últimamente
Mario para colocar contenido en una nueva pagina puedes aplicar los siguientes estilos:
page-break-before:always
page-break-after:always
page-break-inside:always
para los elementos que quieres desplazar a una nueva pagina
o también usar new_page dentro del contenido colocando de de la siguiente forma
$html = “Maecenas sit amet risus. Aliquam orci. Vivamus
lacinia mauris ac ipsum. Nullam sagittis odio non
<script type=’text/php’>
$pdf->new_page();
</script>
mi. Praesent dictum arcu vel nisi. Praesent urna”
Erick Reyes el problema que presentas es muy común y se debe a la configuración del php.ini específicamente en los siguientes campos
max_execution_time = 30
max_input_time = 60
memory_limit = 80M
Aumentando el tamaño puedes solucionar el problema ademas trata que tus tablas esten muy bien hechas sin exagerar el numero de columnas y filas ya que la libreria trabaja con DOM y esto hace que se efectúen muchos procesos
Anais lo puedes solucionar colocando margenes a la pagina a través de estilos los datos enviados a la librería crean automáticamente la distribución de las paginas
Saludos
09.11.07 :: 15:33
Gracias por el post
Buenas tardes he echo paso por paso pero a la hora de correr el archivo php me da un error en el servidor y el apache se cierra. Que crees que pueda ser?
Ahhh Cuando descargo el archivo dompdf y lo descomprimo lo crea en una carpeta llamada dompdf-0.5.1 yo lo renombro como dompdf y busco en todos los archivos internos donde aparezca dompdf-0.5.1 y los cambio por dompdf.
Espero contar con tu ayuda
13.11.07 :: 9:23
Que error te da?, puede ser que sea por un bug en el apache tal vez necesites actualizarlo, tal vez estés usando de forma incorrecta algunos bucles, revisalo y me dices.
http://tinyurl.com/2dwqks
03.01.08 :: 6:15
Hola a todos/as.
Recientemente he instalado Dompdf y parece ser que va medio que. Es decir, no tengo problema a la hora de convertir ficheros html pequeños, pero ocurre que convirtiendo un fichero html a pdf, que contiene una tabla de 10 filas, me devuelve el siguiente error:
“Fatal error: Uncaught exception ‘DOMPDF_Exception’ with message ‘Min/max width is undefined for table rows’ in /home/profe/websites/matrera/drupal/mislibrerias/dompdf/include/table_row_frame_reflower.cls.php:89 Stack trace: #0 /home/profe/websites/matrera/drupal/mislibrerias/dompdf/include/frame_decorator.cls.php(390): Table_Row_Frame_Reflower->get_min_max_width() #1 /home/profe/websites/matrera/drupal/mislibrerias/dompdf/include/frame_reflower.cls.php(172): Frame_Decorator->get_min_max_width() #2 /home/profe/websites/matrera/drupal/mislibrerias/dompdf/include/frame_decorator.cls.php(390): Frame_Reflower->get_min_max_width() #3 /home/profe/websites/matrera/drupal/mislibrerias/dompdf/include/cellmap.cls.php(467): Frame_Decorator->get_min_max_width() #4 /home/profe/websites/matrera/drupal/mislibrerias/dompdf/include/cellmap.cls.php(359): Cellmap->add_frame(Object(Inline_Frame_Decorator)) #5 /home/profe/websites/matrera/drupal/mislibrerias/dompdf/include/cellmap.cls.php(359): Cellmap->add_frame(Object(Table_Row_Group_Frame_D in /home/profe/websites/matrera/drupal/mislibrerias/dompdf/include/table_row_frame_reflower.cls.php on line 89.”
Tengo PHP5 y en el php.ini tengo el límite a 128M, así que ya no se me ocurre a que puede ser debido ésto.
A ver si alguien tiene alguna idea.
Gracias por adelantado.
05.01.08 :: 14:25
Creo que tu problema no tiene que ver con memoria ni con la versión de tu php, debe haber algo en tu código que hace que realice una acción por la cual no esta declarando o no esta tomando un valor de una variable necesaria para dompdf, te podría ayudar si me mandas el código para poder chekear pq no podría decirte a ciencia cierta que esta haciendo mal.
Ademas por experimentos propios creo que dompdf es un poco lento y poco funcional para dar pdfs bastante extensos, tratare de colocar un tutorial de otra herramienta mejor
Podéis enviarme el código(no spam
) a emendoza@inventa-design.com
Saludos
31.01.08 :: 16:51
Hola: he intentado utilizar dompdf pero no he logrado hacer ningun pdf, ni con los ejemplo de esta pagina. El servidor de apache se “cuelga”. (utilizo xampp php 5.x) y debo reiniciarlo.
Buscando descubri que esto ocurre cuando llega a la linea 410 de dompdf.cls.php dentro de include :
$this->_pdf = Canvas_Factory::get_instance($this->_paper_size, $this->_paper_orientation);
hasta la linea anterior llega, he utilizado die; para ver hasta donde llegaba. Alguna idea? agradeceria ayuda a la brevedad, ya que tengo que entregar un trabajo.
Gracias.
31.01.08 :: 17:30
Ya resolvi el problema a medias, en el servidor me faltaba derechos en la carpeta font dentro de lib. Solucionado. ahora, para probarlo en mi pc alguien sabe como solucionar esto? tenxo XP y xampp y no se como darle derechos a la carpeta.
Gracias
01.02.08 :: 8:35
Otra consulta: estooy generando el pdf desde un php, pero me el siguiente error:
Fatal error: Call to a member function get_cellmap() on a non-object in /home/sitio/public_html/dompdf/include/table_cell_frame_reflower.cls.php on line 64
el php genera un reporte con bastantes datos , codigo javascript (no se si sera eso el problema)
Gracias.
01.02.08 :: 19:20
Hola yo tengo un problema cuando genero el pdf desde un php me sale este error pero no le entiendo me podrías ayudar gracias. Unable to stream pdf: headers already sent
11.02.08 :: 3:09
Hola, tengo el mismo problema que Gabriel.
Al ejecutar el código de prueba me da este error “Unable to stream pdf: headers already sent”
Gracias.
11.02.08 :: 17:27
Para grabriel y yeni ese error es porque no se puede mandar a escribir nada junto con el pdf es como cuando usas el redireccionamiento en php header(location…) si se manda algo a la salida genera un error..
12.02.08 :: 16:09
muy bueno la guía pero tengo problemas cuando quiero trabajar con paginas dinámicas con base de datos tengo este error
Parse error: parse error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in D:\AppServ\www\monitor07\ZZZprueba.php on line 1141
quisas me puedas ayudar en lalinea se encuentra este campo
$zfe=$rowausen[’fecini_ause’];
espero me puedas ayudar
24.03.08 :: 10:42
Excelente! Muy bien explicado, me ha servido mucho! En especial lo de cabecera y pie de página, Salu2!
08.04.08 :: 10:02
Hola, existe la posibilidad de guardar-lo i tambien sacarlo por stream a la vez? Gracias
08.04.08 :: 14:03
hola soy estudiante del ultimo semestre en informatica, estoy desarrollando un sistema con php,dreamweaver y mysql..ya estoy por terminar, pero en estos momentos m encuentro trancada en los reportes…soy una principiante y estoy trabajando con php para los reportes en pdf…los estoy creando de modo texto..pero tengo problemas debido a que los datos aparecen unos encima de otro en algunas lineas…porq sera esto porfa el q pueda me ayude…gracias..
15.04.08 :: 8:33
Hola, estuve probando tus consejos y me han funcionado bien pero tengo una inquietud acerca del PDF, es que yo necesito guardarlo automaticamente y no que me lo abra….tu sabes como puedo lograr esto…….
Gracias
21.04.08 :: 13:53
Hola a todos, esta muy buena la libreria, lo que no logro es incrustar un swf en el PDF alguien me puede ayudar con esto si se puede.
Muchas Gracias.
Comentar