Crear PDF usando HTML

Para crear PDF usando HTML con PHP existen diferentes librerías que nos pueden ayudar a cumplir el objetivo de manera sencilla, esta vez vamos a probar mPDF. mPDF es una librería en PHP la cual permite generar archivos PDF usando HTML(Codificado con UTF-8). Está basada en FPDF y HTML2FPDF, con varias mejoras, fue escrito por Ian Back y lanzado bajo licencia GNU GPL v2.

Instalación de mPDF

El método de instalación oficial de mPDF en PHP es via composer y este es el paquete packagist: mpdf/mpdf.

composer require mpdf/mpdf

Cargando la librería

Como es un ejemplo básico realizaremos la carga de la librería sólo en el controlador que vamos a usar. De la siguiente manera:

Archivo: default/app/controllers/index_controller.php

<span class="token delimiter"><?php</span>
<span class="token comment">// Require composer autoload</span>
<span class="token keyword">require_once</span> <span class="token constant">APP_PATH</span> <span class="token punctuation">.</span> <span class="token string">'../../vendor/autoload.php'</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Mpdf<span class="token punctuation">\</span>Mpdf</span><span class="token punctuation">;</span>
<span class="token comment">/**
 * Controller por defecto si no se usa el routes
 *
 */</span>
<span class="token keyword">class</span> <span class="token class-name">IndexController</span> <span class="token keyword">extends</span> <span class="token class-name">AppController</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">index</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

Primer ejemplo de crear PDF usando HTML

Creamos el método example1() donde sin usar vista o template creamos el «Hola mundo» del uso de la librería con el siguiente código:

Archivo: default/app/controllers/index_controller.php

<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">example1</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//Importante: Sin vista y sin tamplate</span>
    View<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//Crea una instancia de la clase y le pasa el directorio default/app/temp/</span>
    <span class="token variable">$mpdf</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Mpdf</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'tempDir'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token constant">APP_PATH</span> <span class="token punctuation">.</span> <span class="token string">'/temp'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//Escribe algo de contenido HTML:</span>
    <span class="token variable">$mpdf</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">WriteHTML</span><span class="token punctuation">(</span><span class="token string">'¡Hola KumbiaPHP!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//Envía un archivo PDF directamente al navegador</span>
    <span class="token variable">$mpdf</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">Output</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Dependiendo de la configuración del navegador nos mostrará en su visualizador de PDFs el documento creado. En caso contrario nos mostrará el diálogo para iniciar la descarga.

Ejemplo de crear PDF con HTML
Ejemplo de crear PDF con HTML

Segundo ejemplo ¡Usaremos vistas!

El primer ejemplo está bien, pero a nosotros nos gusta darle más orden y para mantener la lógica en su lugar. Vamos a crear un modelo llamado HtmlToPdf (Pueden llamarlo como deseen) y es donde a partir de ahora vamos a crear los archivos PDF, pero esta vez llamaremos el contenido de un partial, el cual nos servirá para mantener separado el HTML del PHP. Primero observemos el contenido del partial:

Archivo: default/app/views/_shared/partials/pdf/example2.phtml

<h1>¡Hola KumbiaPHP!</h1>

Ahora si el método example2() en el modelo:

Archivo: default/app/models/html_to_pdf.php

<span class="token delimiter"><?php</span>
<span class="token keyword">use</span> <span class="token package">Mpdf<span class="token punctuation">\</span>Mpdf</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">HtmlToPdf</span> <span class="token punctuation">{</span>
    
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function">example2</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token comment">// Activa el almacenamiento en búfer de la salida</span>
        <span class="token function">ob_start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// Carga el contenido del partial</span>
        View<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">partial</span><span class="token punctuation">(</span><span class="token string">'pdf/example2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// Obtiene en $html el contenido del búfer actual y elimina el búfer de salida actual</span>
        <span class="token variable">$html</span> <span class="token operator">=</span> <span class="token function">ob_get_clean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// Crea una instancia de la clase y le pasa el directorio temporal</span>
        <span class="token variable">$mpdf</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Mpdf</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'tempDir'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token constant">APP_PATH</span> <span class="token punctuation">.</span> <span class="token string">'/temp'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// Escribe algo de contenido HTML:</span>
        <span class="token variable">$mpdf</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">WriteHTML</span><span class="token punctuation">(</span><span class="token variable">$html</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// Envia un archivo PDF directamente al navegador</span>
        <span class="token variable">$mpdf</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">Output</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

Ahora simplemente en el controlador sin usar vista ni template llamaremos el método example2() de la clase modelo HtmlToPdf

Archivo: default/app/controllers/index_controller.php

<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">example2</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//Importante: Sin vista y sin tamplate</span>
    View<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//Llama al ejemplo 2</span>
    HtmlToPdf<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">example2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

El código anterior hace exactamente lo mismo que el primer ejemplo, la diferencia es que esta vez usamos MVC. En el modelo añadimos la lógica para crear el documento pdf a partir de una vista parcial (partial), usamos el controlador para llamar el método implementado en el modelo.

Podemos añadir todo el HTML que deseemos siempre y cuando sea compatible con mPDF, eso nos da juego para añadir tablas, imágenes, enlaces, añadir estilos con css, etc.

Ejemplo 3

Vamos a hacer esta vez que el método del modelo reciba un parámetro $name y se lo pase a la vista parcial (partial) pdf/example3.

<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function">example3</span><span class="token punctuation">(</span><span class="token variable">$name</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">// Activa el almacenamiento en búfer de la salida</span>
    <span class="token function">ob_start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Carga el contenido del partial pasandole datos</span>
    View<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">partial</span><span class="token punctuation">(</span><span class="token string">'pdf/example3'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'name'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$name</span><span class="token punctuation">,</span> <span class="token string">'date'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token function">date</span><span class="token punctuation">(</span><span class="token constant">DATE_ISO8601</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Obtiene en $html el contenido del búfer actual y elimina el búfer de salida actual</span>
    <span class="token variable">$html</span> <span class="token operator">=</span> <span class="token function">ob_get_clean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Crea una instancia de la clase y le pasa el directorio temporal</span>
    <span class="token variable">$mpdf</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Mpdf</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'tempDir'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token constant">APP_PATH</span> <span class="token punctuation">.</span> <span class="token string">'/temp'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Escribe algo de contenido HTML:</span>
    <span class="token variable">$mpdf</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">WriteHTML</span><span class="token punctuation">(</span><span class="token variable">$html</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Obliga la descarga del PDF y se personaliza el nombre</span>
    <span class="token variable">$mpdf</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">Output</span><span class="token punctuation">(</span><span class="token string">'example3.pdf'</span><span class="token punctuation">,</span> \<span class="token package">Mpdf<span class="token punctuation">\</span>Output<span class="token punctuation">\</span>Destination</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">DOWNLOAD</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Ahora haremos que el partial reciba el valor de las variables y las imprima para que se muestre en el PDF.

Archivo: default/app/views/_shared/partials/pdf/example3.phtml

<span class="token operator"><</span>h1<span class="token operator">></span>¡Hola <span class="token delimiter"><?</span><span class="token operator">=</span> <span class="token variable">$name</span> <span class="token delimiter">?></span><span class="token operator">!</span><span class="token operator"><</span><span class="token operator">/</span>h1<span class="token operator">></span>

<span class="token operator"><</span>p<span class="token operator">></span>
Este documento fue generado el <span class="token delimiter"><?</span><span class="token operator">=</span> <span class="token variable">$date</span> <span class="token delimiter">?></span>
<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span>

Si entramos a la URL: http://localhost:8184/index/example3/Henry nos descargará el PDF con el nombre example3.pdf y veremos algo como la siguiente captura de pantalla:

Ejemplo 3 De HTML a PDF

Ejemplo 3 De HTML a PDF

Estos fueron tres ejemplos básicos para generar PDF usando HTML con PHP.

Segunda Parte de HTML a PDF

Exportar tabla HTML a PDF

Si desean que hagamos un nuevo tutorial con ejemplos avanzados y de la vida real dejen su comentario en la caja de abajo.

Descargar código completo

Como siempre, el código completo del ejemplo para crea documentos PDF con PHP está disponible para todos en el siguiente repositorio en Github listo para usar con Docker: https://github.com/henrystivens/kumbiaphp-mpdf

Nuevos ejemplos de mPDF

Puedes ver un ejemplo del PDF generado más completo funcionando en ejemplo mPDF  y el código PHP de ejemplo controlador y template para usar con cualquier vista de HTML.


9 thoughts on “Crear PDF usando HTML”

  1. Mas que excelente!!! realmente la comunidad es de grandiosa ayuda!. Me han asistido teniendo en cuenta que mi versión de php no era la compatible con composer y finalmente, lo he logrado gracias a @henrystevens y a @joanhey —
    De paso sugiero, en caso de ser posible, algún tutorial como este pero para exportar un datatable a EXCEL.
    Gracias!!!

  2. Buen trabajo @henrystivens, tenia problemas al crear un PDF de forma interna para enviar como adjunto por correo, he podido finalizar desde el controlador donde cambio el estado a un acta con el uso de este tutorial, muy claro y completo.

  3. Hola muy buena explicación, tengo algunas dudas actualmente ya que estoy pasando una cantidad enorme de registros como 20000 que se deben de visualizar en el pdf y llega el momento en donde se detiene el proceso por falta de memoria cabe mencionar que ya hice algunos ajustes para aumentar memoria y tiempo de ejecucion, la pregunta seria si es posible de mandar por grupos de registros he ir construyendo dicho archivo para poder liberar memoria y poder generar dicho pdf

  4. Hola amigo muy buen código pero una pregunta cómo le haces para programar el PDF en la página web pasa hack

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

© Kumbia Team