En este post te mostraré cómo exportar una página web a PDF a través de un botón, enlace o cualquier cosa soportada por JavaScript. A este proceso también se le conoce como convertir HTML a PDF.

Es decir, convertir web a PDF usando programación con JavaScript y las siguientes librerías:
- html2canvas
- jsPDF
- html2pdf
De hecho, html2pdf usa las dos librerías anteriores. Aunque parece complejo, verás que no lo es realmente. Con esta librería podemos crear un PDF muy parecido a la página web, incluyendo imágenes.
Incluyendo librería
Tenemos dos opciones. Incluir el “bundle” que ya tiene las otras dos dependencias, o cargar las 3 dependencias por separado. Recomiendo el bundle, mismo que podemos conseguir aquí.
Nota: tal vez con el paso del tiempo, se cambie la manera de incluir la librería. Aquí te dejo el repositorio del proyecto por si algo ha cambiado.
En mi caso la he descargado, e incluido así:
<!-- El script de la librería-->
<script src="html2pdf.bundle.min.js"></script>
Generando PDF
Al incluir la librería tendremos a la función html2pdf
. Aquí dejo el código y lo explico a continuación.
const $elementoParaConvertir = document.body; // <-- Aquí puedes elegir cualquier elemento del DOM
html2pdf()
.set({
margin: 1,
filename: 'documento.pdf',
image: {
type: 'jpeg',
quality: 0.98
},
html2canvas: {
scale: 3, // A mayor escala, mejores gráficos, pero más peso
letterRendering: true,
},
jsPDF: {
unit: "in",
format: "a3",
orientation: 'portrait' // landscape o portrait
}
})
.from($elementoParaConvertir)
.save()
.catch(err => console.log(err));
const $elementoParaConvertir = document.body; // <-- Aquí puedes elegir cualquier elemento del DOM
html2pdf()
.set({
margin: 1,
filename: 'documento.pdf',
image: {
type: 'jpeg',
quality: 0.98
},
html2canvas: {
scale: 3, // A mayor escala, mejores gráficos, pero más peso
letterRendering: true,
},
jsPDF: {
unit: "in",
format: "a3",
orientation: 'portrait' // landscape o portrait
}
})
.from($elementoParaConvertir)
.save()
.catch(err => console.log(err));
En la línea 1 declaramos el elemento del DOM que se tomará para crear el PDF. Si quieres que se le tome a todo el cuerpo, envía directamente a document.body
. También puedes enviar un div, párrafo, etcétera (puedes usar querySelector).
Después establecemos las opciones con set
. Por ejemplo, establecemos el nombre del PDF generado con JavaScript. También enviamos opciones propias de las librerías html2canvas
y jsPDF
.
Una cosa importante es scale
dentro de html2canvas
, que indica la escala. Entre mayor sea, se notará una mejor calidad, pero será un PDF más pesado o en ocasiones contendrá errores.
En el caso de jsPDF
estamos indicando que el formato sea a3. Puede ser a4, a1, a2, etcétera. Si quieres una buena página para las medidas yo consulté papersizes.org
La orientación se define con orientation
. Puede ser portrait
que es de manera vertical, o landscape
de manera horizontal.
Al invocar al método save
se devuelve una promesa que se resolverá cuando el PDF sea descargado (Se le preguntará al usuario en dónde guardarlo, sugiriendo el nombre especificado en filename
. Recuerda que como es una promesa podemos manejar el catch, then y finally.
Ejemplo de conversión HTML a PDF con JavaScript
Cabe mencionar que esto es compatible con la mayoría de navegadores actuales y decentes. Por favor, usuarios de Internet Explorer, ya es 2020, es hora de actualizar los navegadores.
Como sea, aquí dejo un ejemplo completo y funcional. Tenemos el código HTML. Recuerda que este código puede ser HTML puro, ser preprocesado por PHP u otro lenguaje, etcétera:
<!--
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me /
------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Creado por Parzibyte (https://parzibyte.me). Este encabezado debe mantenerse intacto,
excepto si este es un proyecto de un estudiante.
-->
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Convertir HTML a PDF</title>
<!-- El script de la librería-->
<script src="html2pdf.bundle.min.js"></script>
<!--Nuestro script, que se encarga de crear el PDF usando la librería-->
<script src="script.js"></script>
<!-- Algunos estilos -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Mi página web</h1>
<strong>Presiona el siguiente botón para crear un PDF:</strong>
<button id="btnCrearPdf">Click aquí</button>
<h5>Estamos probando la creación de un PDF desde HTML usando JavaScript</h5>
<a href="https://parzibyte.me/blog/">Creado por Parzibyte</a>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Voluptas dignissimos laudantium laboriosam asperiores?
Doloremque fuga quia odit quas. Obcaecati aliquam suscipit molestias? Architecto nisi blanditiis maxime beatae
temporibus assumenda ex.</p>
<img src="lake-5534341_1280.jpg" alt="Una imagen">
<h1>Otro encabezado</h1>
<table>
<thead>
<tr>
<th>Nombre</th>
</tr>
</thead>
<tbody>
<tr>
<td>Parzibyte</td>
</tr>
</tbody>
</table>
</body>
</html>
Se puede observar que estamos importando el script de la librería, y un script propio que hará el funcionamiento. Además, tenemos un botón que al ser presionado va a generar el documento PDF. Ahora en la parte de programación con JavaScript:
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me /
------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Creado por Parzibyte (https://parzibyte.me). Este encabezado debe mantenerse intacto,
excepto si este es un proyecto de un estudiante.
*/
document.addEventListener("DOMContentLoaded", () => {
// Escuchamos el click del botón
const $boton = document.querySelector("#btnCrearPdf");
$boton.addEventListener("click", () => {
const $elementoParaConvertir = document.body; // <-- Aquí puedes elegir cualquier elemento del DOM
html2pdf()
.set({
margin: 1,
filename: 'documento.pdf',
image: {
type: 'jpeg',
quality: 0.98
},
html2canvas: {
scale: 3, // A mayor escala, mejores gráficos, pero más peso
letterRendering: true,
},
jsPDF: {
unit: "in",
format: "a3",
orientation: 'portrait' // landscape o portrait
}
})
.from($elementoParaConvertir)
.save()
.catch(err => console.log(err));
});
});
Puedes ver el código completo en este enlace. También puedes acceder a la demostración aquí. Finalmente, te dejo un vídeo en YouTube con la explicación adicional: