En esta segunda parte veremos como exportar una tabla HTML a PDF usando la librería mPDF. Si no has visto la primera parte este es el primer artículo: Crear PDF usando HTML donde aprendimos a crear un PDF usando partials y funciones en un modelo.
[Actualización: Abril 2020] Hemos creado un nuevo repositorio llamado Sandbox en Github donde van a estar todos los ejemplos y que podrán visualizar en vivo en la página KumbiaPHP Framework Examples por lo tanto el código se ha mejorado y los links han cambiado.
Template PDF
Un template permite ahorrar código que se repite en la vistas, permitiendo así un fácil mantenimiento y separación del contenido. Realizará la carga de librería, la cabecera y el pié de página y por supuesto el contenido que queremos mostrar.
Para los que aun no han visto el tema de templates en KumbiaPHP o tienen dudas de su funcionamiento los invito a leer la sección sobre el manejo de vistas en KumbiapHP. A continuación el código completo del template y más abajo con capturas se explica cada parte importante.
Archivo: app/views/_shared/templates/pdf/mpdf.phtml
<?php
use Mpdf\Mpdf;
/* Defaults */
// fileName
$fileName = $filename ?? "Reporte-de-$controller_name";
// Title
$title = $title ?? "Reporte de $controller_name";
// CSS
$css = $css ?? 'css/pdf.css';
// Destination I show in browser D download
$destination = isset($download) && $download ? 'D' : 'I';
//Activa el almacenamiento en búfer de la salida
ob_start();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title><?= $title ?></title>
<link rel="stylesheet" type="text/css" href="<?= $css ?>">
<meta name="author" content="KumbiaPHP framework">
<meta name="description" content="PDF output example with KumbiaPHP framework">
<meta name="keywords" content="kumbiaphp, php, pdf, mpdf, examples">
<body>
<htmlpageheader name="myHeader1">
<section id="page-header">
<a href="https://www.kumbiaphp.com"><img src="img/kumbiaphp.svg" alt="Logo KumbiaPHP"></a>
<p>Powered by</p>
</section>
</htmlpageheader>
<?php View::content() ?>
<htmlpagefooter name="myFooter1">
<section id="page-footer">
<div id="printed-date">{DATE d/m/Y}</div>
<div id="page-number">{PAGENO}/{nbpg}</div>
</section>
</htmlpagefooter>
</body>
</html>
<?php
$html = ob_get_clean();
ob_clean();
// Crea una instancia de la clase y le pasa el directorio temporal
$mpdf = new Mpdf([
'tempDir' => APP_PATH . 'temp/mpdf',
'format' => 'A4',
'title2annots' => true, // convert headers <hx> in annotations
'mirrorMargins' => 0, // mirror the left and right margin values on odd and even pages
'exposeVersion' => false // security
// more variables in https://mpdf.github.io/reference/mpdf-variables/overview.html
]);
// Escribe el contenido HTML (Template + View):
$mpdf->WriteHTML($html);
// Genera el PDF, ya sea para su descarga o visualización en el navegador
$mpdf->Output("$fileName.pdf", $destination);
El proyecto ya usa el autoload de composer para tener disponible mPDF y simplemente importa Mpdf\Mpdf. Luego se definen algunas variables para personalizar el PDF y se ejecuta la función ob_start(). «Esta función activará el almacenamiento en búfer de la salida. Mientras dicho almacenamiento esté activo, no se enviará ninguna salida desde el script (aparte de cabeceras); en su lugar la salida se almacenará en un búfer interno.»
Si desean conocer como agregar encabezados y pies de páginas con mPDF un compañero realizó un manual en la Wiki de KumbiaPHP que muestra como agregarlos usando las funciones explicadas en el artículo anterior: Exportar a PDF con cabecera y pie de pagina
Ahora en el <body> definimos el contenido de la cabecera y el pie de página, y entre ellos la función View::content() que nos permite mostrar el contenido de la vista.
mPDF maneja sus propias etiquetas, van entre llaves {} y usamos algunas de ellas:
- DATE: Para mostrar la fecha actual
- PAGENO: Número de la página
- nbpg: Número total de páginas del documento
Y la parte final del template es la que se encarga de unir el template con la vista, generar el PDF con ese contenido y hacer que el documento se visualice o descargue.
Controlador PHP
Vamos a crear una nueva vista y para ello empezamos con el método que llamaremos pdf() en el controlador templates_examples_controller.php El código se encuentra explicado entre líneas.
Archivo: app/controllers/templates_examples_controller.php
public function pdf()
{
//Usa el tempalte 'pdf'
View::template('pdf/mpdf');
//Modifica el nombre del archivo a descargar
$this->fileName = 'user-list';
//Modifica el título del documento PDF en la cabecera
$this->title = 'User List';
$this->download = false;
$this->data = User::all(); // data to show (model User from db)
}
Vista HTML
Ahora crearemos la vista la cual tendrá la tabla, recorriendo uno a uno los registro de la consulta realizada por el modelo en el controlador.
Archivo: app/views/templates_examples/pdf.phtml
<?php if (!count($data)) : ?>
<h2>No hay ningún registro</h2>
<?php else : ?>
<table class="report">
<caption class="caption"><?= $title ?></caption>
<thead>
<tr>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Email</th>
<th scope="col">Birthdate</th>
</tr>
</thead>
<tbody>
<?php foreach ($data as $item) : ?>
<tr>
<td><?= $item->first_name ?></td>
<td><?= $item->last_name ?></td>
<td><?= $item->email ?></td>
<td><?= $item->birthdate ?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
No hace falta explicar mucho más de la vista anterior ya que es una vista normal en KumbiaPHP, esta vista es reutilizable por ejemplo si se quiere pasar a un documento Excel o devolver la vista mediante AJAX.
Enlazar al reporte PDF
Y en donde queramos que esté el enlace al reporte PDF simplemente lo añadimos a la vista deseada, nosotros lo hemos añadio a la página de información de los ejemplos de template.
Archivo: app/views/templates_examples/info.pdf.phtml
<a href="/templates-examples/pdf" target="_blank">Export users list</a>
Y al pulsar el botón visualizaremos el documento PDF como el siguiente:
Descargar código completo
Como siempre, el código completo está disponible para todos en el siguiente repositorio en Github listo para usar: https://github.com/KumbiaPHP/Sandbox/