Convertir documentos en Node.js: herramientas de código abierto
La conversión de documentos es un requisito frecuente en las aplicaciones de Node.js, ya sea que generes PDF a partir de HTML, crees facturas o exportes informes. Por suerte, el ecosistema de Node.js ofrece varias bibliotecas de código abierto sólidas que simplifican estas tareas. Exploremos algunas de las mejores opciones disponibles, junto con ejemplos prácticos que te ayudarán a elegir la herramienta adecuada para tu proyecto.
Estos ejemplos renderizan o generan PDF; no convierten archivos arbitrarios de Word, de hojas de
cálculo o de PDF a otros formatos editables. Usa Node.js 22.12 o una versión posterior para los
ejemplos del servidor y guarda cada uno como un archivo .cjs
independiente. El ejemplo de jsPDF se ejecuta en un navegador.
Bibliotecas populares de código abierto para la conversión de documentos
Estas son algunas bibliotecas de uso extendido:
- Puppeteer: automatización de Chrome headless para convertir HTML a PDF.
- PDFKit: generación de PDF del lado del servidor con una amplia personalización.
- jsPDF: generación de PDF del lado del cliente directamente en el navegador.
- wkhtmltopdf: herramienta de línea de comandos archivada para flujos de trabajo heredados de HTML a PDF.
Veamos cada una de ellas en detalle.
Conversión de HTML a PDF con Puppeteer
Puppeteer es una potente biblioteca de Node.js que ofrece una API de alto nivel para controlar Chrome (o Chromium) headless, lo que la hace ideal para convertir páginas HTML en PDF. Renderiza con precisión las páginas web, incluidos el CSS y el JavaScript.
Ejemplo de uso
Instala Puppeteer, que además descarga un navegador Chrome compatible:
npm install puppeteer@25
Renderiza únicamente URL y HTML que tú controles. Un servicio en producción que acepte URL arbitrarias necesita aislamiento de red y validación de solicitudes para impedir el acceso a servicios internos.
const puppeteer = require('puppeteer')
async function htmlToPdf(url, outputPath) {
const browser = await puppeteer.launch()
try {
const page = await browser.newPage()
const response = await page.goto(url, { waitUntil: 'networkidle0' })
if (!response || !response.ok()) {
throw new Error(`Page load failed: ${response?.status() ?? 'no HTTP response'}`)
}
await page.pdf({ path: outputPath, format: 'A4' })
} finally {
await browser.close()
}
}
htmlToPdf('https://example.com', 'example.pdf').catch((error) => {
console.error(error.message)
process.exitCode = 1
})
Ventajas y desventajas
- Ventajas: renderizado preciso, compatibilidad con CSS y JavaScript modernos, puede manejar aplicaciones de página única (SPA).
- Desventajas: mayor uso de recursos debido al navegador headless, puede ser más lento que otros métodos.
Generar PDF con PDFKit
PDFKit es una biblioteca versátil para crear PDF mediante programación en el lado del servidor. Permite un control detallado sobre el contenido y el diseño del PDF.
Ejemplo de uso
npm install pdfkit@0.17
Espera a que el stream de salida termine para que los errores de disco se informen antes de dar la operación por exitosa:
const PDFDocument = require('pdfkit')
const fs = require('fs')
const { pipeline } = require('node:stream/promises')
async function createPdf(outputPath) {
const doc = new PDFDocument()
const writing = pipeline(doc, fs.createWriteStream(outputPath))
try {
doc.fontSize(25).text('Hello, PDFKit!', 100, 100)
doc.fontSize(12).text('This is a sample PDF generated using PDFKit.', 100, 150)
doc.end()
} catch (error) {
doc.destroy(error)
}
await writing
}
createPdf('output.pdf').catch((error) => {
console.error(error.message)
process.exitCode = 1
})
Ventajas y desventajas
- Ventajas: muy personalizable, ligera, buena para generar PDF desde cero.
- Desventajas: requiere gestionar el diseño manualmente, puede resultar compleja para diseños intrincados.
Generación de PDF del lado del cliente con jsPDF
jsPDF permite generar PDF directamente en el navegador, a menudo en combinación con html2canvas para capturar contenido HTML y convertirlo en una imagen, que luego se añade al PDF.
Ejemplo de uso
<script src="https://cdn.jsdelivr.net/npm/jspdf@4.2.1/dist/jspdf.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
<div id="content">Hello, jsPDF!</div>
<button id="download">Download PDF</button>
<p id="status" role="status"></p>
<script>
async function generatePDF() {
const { jsPDF } = window.jspdf
const content = document.getElementById('content')
const canvas = await html2canvas(content)
const imgData = canvas.toDataURL('image/png')
const pdf = new jsPDF()
const width = pdf.internal.pageSize.getWidth() - 20
const height = pdf.internal.pageSize.getHeight() - 20
const scale = Math.min(width / canvas.width, height / canvas.height)
pdf.addImage(imgData, 'PNG', 10, 10, canvas.width * scale, canvas.height * scale)
pdf.save('download.pdf')
}
document.getElementById('download').addEventListener('click', async () => {
const status = document.getElementById('status')
status.textContent = ''
try {
await generatePDF()
} catch {
status.textContent = 'Unable to generate the PDF. Please try again.'
}
})
</script>
Esto ajusta una captura de pantalla a una sola página. El contenido largo se vuelve más pequeño y la imagen resultante no tiene texto seleccionable ni estructura de documento para los lectores de pantalla. Usa un diseño de PDF basado en texto cuando se requieran esas capacidades; html2canvas también necesita recursos de imagen del mismo origen o con CORS habilitado.
Ventajas y desventajas
- Ventajas: no requiere procesamiento del lado del servidor, integración sencilla, adecuada para aplicaciones del lado del cliente.
- Desventajas: control de estilos y de diseño limitado en comparación con las soluciones del lado del servidor; el renderizado puede diferir ligeramente del HTML original debido a las limitaciones de html2canvas.
Conversión avanzada con wkhtmltopdf
wkhtmltopdf convierte HTML a PDF con un motor antiguo de Qt WebKit. Su repositorio se archivó en enero de 2023, y ya no recibe mantenimiento. Este ejemplo es para instalaciones existentes que procesan únicamente HTML de confianza. La guía de seguridad del proyecto advierte contra las entradas no confiables. Usa un renderizador con mantenimiento activo, como Puppeteer, para aplicaciones nuevas.
Ejemplo de uso
const { execFile } = require('node:child_process')
execFile('wkhtmltopdf', ['https://example.com', 'output.pdf'], (error) => {
if (error) {
console.error(`Error: ${error.message}`)
process.exitCode = 1
return
}
console.log('PDF generated successfully')
})
Ventajas y desventajas
- Ventajas: puede preservar los flujos de trabajo por lotes existentes creados en torno a su motor de renderizado más antiguo.
- Desventajas: requiere un binario externo, carece de mantenimiento y de compatibilidad con los navegadores modernos, y no debe procesar HTML no confiable.
Elegir la biblioteca adecuada
Ten en cuenta estos factores al seleccionar una biblioteca:
- Complejidad: Puppeteer admite diseños modernos y contenido dinámico. Reserva wkhtmltopdf para flujos de trabajo heredados de confianza.
- Rendimiento: PDFKit es ligera y rápida para generar PDF sencillos desde cero. Si la velocidad es crítica y la estructura de tu PDF es relativamente simple, PDFKit es una candidata sólida.
- Entorno: jsPDF es ideal para aplicaciones del lado del cliente en las que quieres generar PDF directamente en el navegador del usuario.
- Dependencias: wkhtmltopdf requiere instalar un binario aparte, mientras que las demás son bibliotecas puras de Node.js (aunque Puppeteer gestiona su propio binario de Chromium/Chrome).
Evalúa las necesidades específicas de tu proyecto para elegir la mejor opción. Por ejemplo, si necesitas generar facturas con un diseño uniforme, PDFKit podría ser una buena elección. Si necesitas convertir a PDF una página web compleja y con mucho JavaScript, Puppeteer sería más adecuado.
La conversión de documentos de Transloadit
Si buscas una solución gestionada, el
servicio de procesamiento de documentos de Transloadit ofrece
sólidas capacidades de conversión de documentos mediante su Robot /document/convert.
Puedes integrarlo fácilmente en tus aplicaciones de Node.js con nuestro
node-sdk.
