Exportar PDFs en Angular con jsPDF

Pasos para poder crear PDFs y exportarlos desde Angular con la librería jsPDF

Anartz Mugika Ledo🤗
7 min readSep 13, 2020

En este tutorial de Angular, os voy a enseñar los pasos que tenemos que completar para poder exportar ficheros de tipo PDF desde una aplicación de Angular utilizando el paquete NPM jsPDF.

Con lo que aprenderemos, seremos capaces de generar documentos de tipo factura, albaranes, tickets, tarjetas,… totalmente personalizados con sus estilos y seleccionando lo que queramos para tal fin.

Luego tendremos la opción de profundizar mediante su documentación oficial.

En una aplicación web, podemos crear PDF utilizando métodos de impresión del navegador, una herramienta de terceros, desde el backend con librerías como html-pdf y también podemos descargar el PDF desde el lado del cliente, que será nuestro objetivo actual.

Podemos encontrar varios paquetes de NPM disponibles para este propósito:

Aunque existan varias opciones, nosotros nos vamos a decantar por jsPdF que es un módulo basado en Javascript, principalmente utilizado para generar archivos PDF desde el lado cliente.

Nos ofrece una gran cantidad de métodos que nos va a permitir personalizar la vista del PDF a nuestras preferencias y gustos.

La documentación oficial de jsPDF la podéis encontrar en el siguiente enlace.

1.- ¿Qué es un fichero PDF?

PDF (siglas en inglés de Portable Document Format, «formato de documento portátil») es un formato de almacenamiento para documentos digitales independiente de plataformas de software o hardware. Este formato es de tipo compuesto (imagen vectorial, mapa de bits y texto). (Definición sacada desde la Wikipedia)

Los ficheros pueden contener textos, imágenes, hipervínculos, video, botones interactivos y más.

Si queréis saber más acerca de los ficheros PDF, acceder a la URL con la información de la Wikipedia.

2.- Requisitos antes de empezar a trabajar con el proyecto

  • NodeJS y NPM instalados en su última versión (Si es la estable, LTS, mejor)
  • Angular CLI instalado.

3.- Crear el proyecto y primer inicio

Creamos el proyecto sin configuración de rutas y con la configuración de la hoja de estilos CSS.

ng new angular-pdf --routing=false --style=css

Usamos el siguiente comando para iniciar nuestra aplicación en desarrollo cuando esté creado el proyecto:

ng serve --open

Ahora que ya lo tenemos en marcha y hemos visto que no hay problemas, seguimos hacia adelante.

4.- Instalación de los paquetes necesarios

Instalamos el paquete de bootstrap para los aplicar estilos de una manera más sencilla:

npm install bootstrap

Ahora que ya tenemos el paquete bootstrap instalado, vamos a proceder con la instalación de los paquetes que necesitaremos para renderizar el fichero PDF desde nuestro proyecto de Angular:

npm install jspdf@1.5.3 html2canvasnpm install @types/jspdf @types/html2canvas -D 
// en dependencias desarrollo con "-D"

Una vez que hemos realizado las instalaciones, tenemos que añadir la referencias de los estilos de bootstrap en el apartado de “styles” y tenemos que añadir los scripts de jsPDF y html2canvas, para poder utilizarlos en nuestro proyecto dentro del fichero angular.json:

Lo que debemos de añadir en el fichero de angular.json dentro de nuestro proyecto

Esto sería lo que tendríamos que tener en cuenta dentro del fichero:

Ahora que ya tenemos esto añadido, podremos usar los estilos de bootstrap y los scripts correspondientes para jsPDF y html2canvas, aunque en el caso de los scripts, para hacerlo sin problemas tenemos que configurar una propiedad dentro del tsconfig.json, para evitar un error. Seguimos en el siguiente punto para hacer este paso.

5.- Configurar el apartado de importaciones desde módulos sin exportación

Ahora para poder trabajar con jsPDF como html2canvas debemos de configurar dentro de la configuración de typescript de nuestro proyecto, el apartado allowSyntheticDefaultImports.

Esto servirá para poder permitir importaciones predeterminadas desde módulos que no tienen exportación predeterminada. Esto no afectará a la emisión del código, simplemente para la verificación a la hora de compilar.

Vamos a ello y actualizamos tsconfig.base.json o tsconfig.json

Dependiendo de la versión, tendremos que usar una opción u otra. El primer fichero lo tenemos disponible con Angular 10 y el segundo con los proyectos de Angular 9 o menos.

Añadimos allowSyntheticDefaultImports dentro compilerOptions

"allowSyntheticDefaultImports": true

Ahora importamos la librería jsPDF en cualquier componente, dependiendo de nuestras necesidades, para poder exportar ficheros PDF con Angular.

import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';

Yo en mi caso, lo voy a añadir en el app.component.html, para no complicarme mucho la vida y seguir con este artículo.

5.- Creamos nuestro primer fichero PDF desde Angular.

Teniendo todo instalado y configurado todo correctamente, cogemos el componente app.component.ts (podría ser otro que sea de nuestro agrado) y añadimos lo siguiente.

import { Component } from '@angular/core';
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas'; // Todavía no lo usamos
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor() {
this.downloadPDF();
}
public downloadPDF(): void {
const doc = new jsPDF();

doc.text('Hello world!', 10, 10);
doc.save('hello-world.pdf');
}
}

Lo que hace ese componente es sencillo:

Tenemos un constructor que llama a una función “downloadPdf()” donde se crea en nuevo documento y mediante la función save, se habilita para descargar el fichero con el nombre “hello-world.pdf” (esto puede hacerse personalizado poniendo otro nombre, haciéndolo dinámico…).

El resultado en este momento será el siguiente:

6.- Añadir información fake

Añadiremos 6 registros con información, para poder tener algo con lo que trabajar en este artículo.

VIDEOGAMES = [
{
id : 1,
name: "Animal Crossing",
platform: "Nintendo Switch",
reference : "1-770-736-8031"
},
{
id: 2,
name: "The Legend of Zelda: Ocarina of Time CV",
platform: "Wii U",
reference: "1-770-736-2323"
},
{
id: 3,
name: "Metal Gear Solid",
platform: "Playstation (PSX)",
reference: "1-4564-736-334"
},
{
id: 4,
name: "ShenMue",
platform: "Sega Dreamcast",
reference: "3-770-736-4532"
},
{
id: 5,
name: "Rise of the Tomb Raider",
platform: "Playstation 4",
reference: "1-324-736-3245"
},
{
id: 6,
name: "Resident Evil 2",
platform: "Playstation",
reference: "1-123-3336-4321"
}
];

Esto lo añadiremos antes del constructor como propiedad para usarlo como base para los datos del PDF que vamos a construir. Lo interesante es que uséis información real y que proviene de una API.

7.- Preparando el HTML que usaremos para el PDF

Vamos a app.component.html y añadimos lo siguiente, para crear una tabla con la información de los juegos.

Hay que prestar atención en el apartado donde añadimos el id=”htmlData” que será muy importante, ya que esté contenido será el que usemos para plasmar esa información dentro del PDF que vamos a crear.

Tiene que tener una apariencia similar a lo siguiente:

8.- Configurando los parámetros de la generación del fichero PDF

Ahora que ya tenemos preparado el apartado de lo que es la vista, para que podamos coger esa información de los videojuegos, tenemos que añadir el código del componente de la siguiente manera:

Código del app.component.ts

Tenemos que tener en cuenta estos aspectos:

const DATA = document.getElementById(‘htmlData’);

Asignamos en “DATA” el contenido de la tabla y el título “Lista de videojuegos…” para poder usarlo en la generación del PDF como la información que queremos mostrar.

const doc = new jsPDF(‘p’, ‘pt’, ‘a4’);

Iniciamos el valor “doc” que será el objeto del documento para generar el PDF añadiendo la orientación “p” (Portrait = vertical), la unidad de media como “pt” y el tamaño del PDF, “A4”.

html2canvas(DATA, options).then((canvas) => {

const img = canvas.toDataURL(‘image/PNG’);

// Añadir imagen Canvas a PDF
const bufferX = 15;
const bufferY = 15;
const imgProps = (doc as any).getImageProperties(img);
const pdfWidth = doc.internal.pageSize.getWidth() — 2 * bufferX;
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
doc.addImage(img, ‘PNG’, bufferX, bufferY, pdfWidth, pdfHeight, undefined, ‘FAST’);
return doc;
}).then((docResult) => {
docResult.save(‘juegos.pdf’);
});

Este apartado es importante, ya que va a ser el punto donde vamos a crear una imagen mediante el canvas teniendo en cuenta la información que hemos obtenido desde el id “htmlData”.

Le vamos a asignar las propiedades de las página, ubicación y con ello en el resultado, creamos el fichero PDF con el nombre que especificamos.

9.- Obteniendo la información de la tabla en un PDF

Una vez llegados a este punto, lo único que nos queda es hacer click, donde conseguiremos que después de un breve instante estemos descargando el fichero PDF que se acaba de generar teniendo en cuenta la información extraída dándonos la opción de poder visualizarlo una vez que esté descargado podremos visualizarlo de la siguiente manera:

10.- Código del proyecto final

Os dejo el contenido del código resultante:

11.- Invítame a un café

Si el contenido que habéis visto creéis que os ha sido útil y me queréis apoyar, podéis invitarme a un café:

https://www.buymeacoffee.com/mugan86

--

--

Anartz Mugika Ledo🤗

[{#frontend:[#mobile:{#android, #kotlin, #ionic}}, {#web:{#angular, #qwik, #bootstrap}}],{#backend: [{#graphql, #nestjs,#express, #mongodb, #mysql}]}]