Generar PDF desde NodeJS

  • Por
Cómo generar archivos en formato PDF desde aplicaciones realizadas en NodeJS con html-pdf. Agregar encabezamientos y pies de página.

En NodeJS existen diversas librerías para la generación de archivos PDF. No las he probado todas, pero la que más me ha gustado de las que he usado, y que me permite el grado de personalización deseado, es el paquete npm html-pdf.

Lo que me resulta muy interesante de este proyecto es que permite crear los PDF a partir de una página web, de un poco de código HTML. Además tiene la posibilidad de agregar cabeceras y pies de página a cada documento del PDF, de una única vez, lo que resulta bastante útil para hacer PDFs con un aspecto más corporativo. Todos aspectos que resultan muy útiles a la hora de generar las versiones imprimibles en PDF de los manuales de DesarrolloWeb.com

Puedes ver el proyeto html-pdf en GitHub para más información. En este artículo te daremos una aproximación y un código para explotar varias de sus características más útiles, como la creación de cabeceras y pies, números de página, estilos personalizados, etc.

Nota: Este pequeño taller asume que tienes un conocimiento medio de NodeJS. Si no es así, te recomendamos leer el Manual de NodeJS.

Dependencia de html-pdf: PhantomJS

Este paquete para la generación de los PDF tiene una dependencia importante. Nada que sea preocupante, ya que las dependencias las mantenemos vía npm como en cualquier otro proyecto, pero cabe señalarla porque sin ella es imposible que funcione bien.

Se trata del proyecto PhantomJS, que básicamente sirve para interaccionar con una página web de manera automática. Está pensado para realizar testing, capturas de pantalla, etc. Pero en este caso html-pdf lo usa para interpretar el contenido de la página que debe ser volcado en el PDF.

Es importante pues instalar html-pdf con npm, y cerciorarse que también se realiza la instalación en local de PhantomJS. La instalación la lanzas con el comando:

npm install html-pdf

Durante la instalación verás que también se instala PhantomJS.

Uso sencillo de html-pdf

Ahora, veamos un pequeño código donde usamos el paquete html-pdf para crear un PDF simple, a partir de un poco de código HTML.

var pdf = require('html-pdf');

var contenido = `
<h1>Esto es un test de html-pdf</h1>
<p>Estoy generando PDF a partir de este código HTML sencillo</p>
`;

pdf.create(contenido).toFile('./salida.pdf', function(err, res) {
    if (err){
        console.log(err);
    } else {
        console.log(res);
    }
});

Como puedes ver:

  • Hacemos el require de html-pdf
  • Creamos una variable con un poco de contenido HTML.
  • Invocamos al método create() de html-pdf, que recibe al menos el contenido que quieres realizar.
  • Se redirecciona la salida a un archivo, encadenando el método toFile, en el que indicamos la ruta del archivo PDF que queremos como salida, en este caso "./salida.pdf".
  • La última función anónima es un callback para hacer cualquier cosa cuando el PDF ha terminado de generarse.

Ese código generará un PFD como este:

Es cierto que era un HTML bastante sencillo y el PDF por tanto ha sido bien simple. Pero la librería aguanta con HTML mucho más sofisticado y tiene soporte a elementos complejos como lo pueden ser SVG o Canvas.

Opciones de configuración de html-pdf

La gracia de este paquete es que permite una variada gama de configuraciones que nos pueden resultar muy útiles.

Para definir la configuración del PDF a generar se escribe un objeto JSON que se manda como segundo parámetro en el método create().

Ese objeto puede tener esta forma:

var options = {
 "format": 'A4',
 "header": {
     "height": "60px"
 },
 "footer": {
     "height": "22mm"
 },
 "base": 'file://Users/midesweb/carpeta_base/'
};

Esa es la configuración que uso en los PDF de los manuales de DesarrolloWeb.com. En GitHub puedes encontrar el listado de configuraciones posible.

Hay un parámetro especialmente útil "base" que sirve para indicar lo que en HTML haríamos con la etiqueta BASE. Es una URL a una carpeta donde están los archivos externos del HTML, es decir, imágenes, CSS y otros ficheros. Todas las rutas relativas en el código HTML que se use para crear el PDF serán relativas a esta carpeta.

Cabeceras y pies de página en el PDF

Esta fue sin duda la funcionalidad que más me atrajo de html-pdf. Puedes crear todo tipo de encabezados y pies de página para tu documento. Incluso puedes configurar la cabecera y el pie de manera personalizada en las páginas que necesites.

En el JSON anterior habrás apreciado que las cabeceras y pies se pueden configurar con algunos valores. Su contenido también se puede definir desde el propio JSON, sin embargo es mucho más fácil hacerlo en el propio código HTML que usamos como fuente.

Para colocar cabeceras y pies tenemos que usar elementos a los que les colocamos un identificador específico como "pageHeader" o "pageFooter". Pero también puedes definir cabecera o pie específico para la primera página con "pageHeader-first" o "pageFooter-first". Existen otros ids como "pageFooter-last", "pageHeader-2", "pageFooter-3"...

Este es el código de mi cabecera y pie de página en un manual de DesarrolloWeb.com (Este código debe estar dentro de la cadena con el HTML que usas para generar el PDF, es decir, forma parte del documento HTML que conviertes a PDF).

<div id="pageHeader" style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">
  <img src="http://desarrolloweb.com/images/logodwgris.png" width="150" height="27" align="left">
  <p style="color: #666; margin: 0; padding-top: 12px; padding-bottom: 5px; text-align: right; font-family: sans-serif; font-size: .85em">
    Publicar en Internet
  </p>
</div>
<div id="pageFooter" style="border-top: 1px solid #ddd; padding-top: 5px;">
  <p style="color: #666; width: 70%; margin: 0; padding-bottom: 5px; text-align: let; font-family: sans-serif; font-size: .65em; float: left;">http://desarrolloweb.com/manuales/publicar-webs-internet.html</p>
  <p style="color: #666; margin: 0; padding-bottom: 5px; text-align: right; font-family: sans-serif; font-size: .65em">Página {{page}} de {{pages}}</p>
</div>

Te lo comparto para que veas como soluciono algunos problemas con los que me he encontrado.

  • La cabecera o el pie no siempre toma el estilo CSS del documento. Es decir, no le afectan los estilos del cuerpo del HTML
  • No me hace caso a las URL relativas ni a la configuración "base" en cabeceras y pies

Además puedes observar cómo se consigue mostrar la página actual y el número de páginas, con las variables {{page}} y {{pages}}.

Conclusión

El paquete npm html-pdf funciona realmente bien. Una vez que configuras un HTML correcto y consigues ajustar las cabeceras y pies de página a los tamaños que te interesan, estilos, etc. obtiene unos resultados muy correctos. Los PDF generados tienen buen aspecto y los elementos se ajustan correctamente a saltos de línea y otras situaciones potencialmente conflictivas.

El contenido de tu PDF se verá muy fiel a la representación de ese código HTML en el navegador.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir