Cómo crear un PDF desde su aplicación web

Publicado: 2022-03-10
Resumen rápido ↬ Hay una gran variedad de opciones cuando se trata de crear un PDF desde una aplicación web. En este artículo, Rachel Andrew echa un vistazo a las herramientas disponibles y comparte sus recomendaciones para ayudarlo a encontrar la herramienta que mejor se adapte a sus necesidades.

Muchas aplicaciones web tienen el requisito de dar al usuario la posibilidad de descargar algo en formato PDF. En el caso de las aplicaciones (como las tiendas de comercio electrónico), esos PDF deben crearse utilizando datos dinámicos y estar disponibles de inmediato para el usuario.

En este artículo, exploraré formas en las que podemos generar un PDF directamente desde una aplicación web sobre la marcha. No es una lista completa de herramientas, sino que mi objetivo es demostrar los diferentes enfoques. Si tiene una herramienta favorita o alguna experiencia propia para compartir, agréguela a los comentarios a continuación.

Comenzando con HTML y CSS

Es probable que nuestra aplicación web ya esté creando un documento HTML utilizando la información que se agregará a nuestro PDF. En el caso de una factura, el usuario podría ver la información en línea y luego hacer clic para descargar un PDF para sus registros. Es posible que esté creando albaranes; una vez más, la información ya se encuentra dentro del sistema. Desea formatearlo de una manera agradable para descargarlo e imprimirlo. Por lo tanto, un buen lugar para comenzar sería considerar si es posible usar ese HTML y CSS para generar una versión en PDF.

CSS tiene una especificación que trata con CSS para impresión, y este es el módulo Paged Media. Tengo una descripción general de esta especificación en mi artículo "Diseño para impresión con CSS", y muchos editores de libros utilizan CSS para toda su producción impresa. Por lo tanto, como CSS en sí mismo tiene especificaciones para materiales impresos, seguramente deberíamos poder usarlo.

La forma más sencilla en que un usuario puede generar un PDF es a través de su navegador. Al elegir imprimir en PDF en lugar de una impresora, se generará un PDF. ¡Lamentablemente, este PDF no suele ser del todo satisfactorio! Para empezar, tendrá los encabezados y pies de página que se agregan automáticamente cuando imprime algo desde una página web. También se formateará de acuerdo con su hoja de estilo de impresión, suponiendo que tenga una.

El problema con el que nos encontramos aquí es el escaso soporte de la especificación de fragmentación en los navegadores; esto puede significar que el contenido de sus páginas se rompe de manera inusual. El soporte para la fragmentación es irregular, como descubrí cuando investigué mi artículo, "Breaking Boxes With CSS Fragmentation". Esto significa que es posible que no pueda evitar la división subóptima del contenido, dejando los encabezados como el último elemento de la página, etc.

Además, no tenemos la capacidad de controlar el contenido de los cuadros de margen de página, por ejemplo, agregar un encabezado de nuestra elección a cada página o numeración de páginas para mostrar cuántas páginas tiene una factura compleja. Estas cosas son parte de la especificación de Paged Media, pero no se han implementado en ningún navegador.

Mi artículo "Una guía sobre el estado de las hojas de estilo de impresión en 2018" sigue siendo preciso en términos del tipo de soporte que tienen los navegadores para imprimir directamente desde el navegador, utilizando una hoja de estilo de impresión.

¡Más después del salto! Continúe leyendo a continuación ↓

Impresión utilizando motores de renderizado de navegador

Hay formas de imprimir en PDF usando los motores de renderizado del navegador, sin pasar por el menú de impresión en el navegador, y terminando con encabezados y pies de página como si hubiera impreso el documento. Las opciones más populares en respuesta a mi tweet fueron wkhtmltopdf e imprimir usando Chrome y Puppeteer sin interfaz gráfica.

wkhtmltopdf

Una solución que se mencionó varias veces en Twitter es una herramienta de línea de comandos llamada wkhtmltopdf. Esta herramienta toma un archivo HTML o varios archivos, junto con una hoja de estilo y los convierte en un PDF. Lo hace mediante el uso del motor de renderizado WebKit.

Esencialmente, por lo tanto, esta herramienta hace lo mismo que imprimir desde el navegador, sin embargo, no obtendrá los encabezados y pies de página agregados automáticamente. En este lado positivo, si tiene una hoja de estilo de impresión en funcionamiento para su contenido, entonces también debería generarse en PDF con esta herramienta, por lo que un diseño simple puede imprimirse muy bien.

Desafortunadamente, sin embargo, seguirá encontrando los mismos problemas que cuando imprime directamente desde el navegador web en términos de falta de compatibilidad con la especificación de medios paginados y las propiedades de fragmentación, ya que todavía está imprimiendo con un motor de renderizado de navegador. Hay algunos indicadores que puede pasar a wkhtmltopdf para volver a agregar algunas de las características que faltan y que tendría de forma predeterminada utilizando la especificación de medios paginados. Sin embargo, esto requiere algo de trabajo adicional además de escribir bien HTML y CSS.

cromo sin cabeza

Otra posibilidad interesante es la de usar Headless Chrome y Puppeteer para imprimir a PDF.

Sin embargo, una vez más, está limitado por la compatibilidad del navegador con los medios paginados y la fragmentación. Hay algunas opciones que se pueden pasar a la función page.pdf() . Al igual que con wkhtmltopdf, estos agregan algunas de las funciones que serían posibles desde CSS si hubiera compatibilidad con el navegador.

Bien puede ser que una de estas soluciones haga todo lo que necesita, sin embargo, si descubre que está librando una especie de batalla, es probable que esté alcanzando los límites de lo que es posible con los motores de renderizado de navegador actuales, y tendrá que buscar una mejor solución.

Polyfills de JavaScript para medios paginados

Hay algunos intentos de reproducir esencialmente la especificación de medios paginados en el navegador usando JavaScript, esencialmente creando un Polyfill de medios paginados. Esto podría brindarle compatibilidad con Paged Media al usar Puppeteer. Eche un vistazo a paged.js y Vivliostyle.

Uso de un agente de usuario de impresión

Si desea quedarse con una solución HTML y CSS, debe buscar un Agente de usuario (UA) diseñado para imprimir desde HTML y CSS, que tiene una API para generar el PDF a partir de sus archivos. Estos agentes de usuario implementan la especificación de medios paginados y tienen mucho mejor soporte para las propiedades de fragmentación de CSS; esto le dará un mayor control sobre la salida. Las opciones principales incluyen:

  • Príncipe
  • casa de la antena
  • PDF Reactor

Un UA de impresión formateará documentos usando CSS, tal como lo hace un navegador web. Al igual que con la compatibilidad del navegador con CSS, debe consultar la documentación de estos UA para averiguar qué admiten. Por ejemplo, Prince (con el que estoy más familiarizado) admite Flexbox pero no CSS Grid Layout en el momento de escribir este artículo. Al enviar sus páginas a la herramienta que está utilizando, normalmente esto sería con una hoja de estilo específica para imprimir. Al igual que con una hoja de estilo de impresión regular, el CSS que usa en su sitio no será apropiado para la versión PDF.

Crear una hoja de estilo para estas herramientas es muy similar a crear una hoja de estilo de impresión regular, tomando el tipo de decisiones en términos de qué mostrar u ocultar, quizás usando un tamaño de fuente o colores diferentes. Entonces podrá aprovechar las características de la especificación de medios paginados, agregando notas al pie, números de página, etc.

En cuanto al uso de estas herramientas desde su aplicación web, deberá instalarlas en su servidor (después de haber comprado una licencia para hacerlo, por supuesto). El principal problema de estas herramientas es que son caras. Dicho esto, dada la facilidad con la que luego puede producir documentos impresos con ellos, es posible que se paguen por sí mismos en el tiempo que se ahorra al desarrollador.

Es posible usar Prince a través de una API, con pago por documento, a través de un servicio llamado DocRaptor. Sin duda, este sería un buen lugar para que muchas aplicaciones comiencen, ya que parecería que sería más rentable alojar las suyas, el costo de desarrollo del cambio sería mínimo.

Una alternativa gratuita, que no es tan completa como las herramientas anteriores pero que puede lograr los resultados que necesita, es WeasyPrint. No implementa completamente todos los medios paginados, sin embargo, implementa más de lo que hace un motor de navegador. Definitivamente, uno para probar!

Otras herramientas que afirman admitir la conversión de HTML y CSS incluyen PDFCrowd, que audazmente afirma admitir HTML5, CSS3 y JavaScript. Sin embargo, no pude encontrar ningún detalle sobre qué era exactamente compatible y si alguna de las especificaciones de Paged Media lo era. También recibió una mención en las respuestas a mi tweet mPDF.

Alejarse de HTML y CSS

Hay una serie de otras soluciones, que se alejan del uso de HTML y CSS y requieren que cree una salida específica para la herramienta. Un par de contendientes de JavaScript son los siguientes:

  • jsPDF
  • pdfhacer

Recomendaciones

Aparte de los enfoques basados ​​en JavaScript, que requerirían que creara una representación completamente diferente de su contenido para imprimir, la belleza de muchas de estas soluciones es que son intercambiables. Si su solución se basa en llamar a una herramienta de línea de comandos y pasarle a esa herramienta su HTML, CSS y posiblemente algo de JavaScript, es bastante sencillo cambiar entre herramientas.

Mientras escribía este artículo, también descubrí un contenedor de Python que puede ejecutar varias herramientas diferentes. (Tenga en cuenta que ya debe tener instaladas las herramientas, sin embargo, esta podría ser una buena manera de probar las diversas herramientas en un documento de muestra).

Para el soporte de Paged Media y la fragmentación, Prince, Antenna House y PDFReactor se destacarán. Como productos comerciales, también vienen con soporte. Si tiene un presupuesto, páginas complejas para imprimir en PDF y su limitación es el tiempo del desarrollador, lo más probable es que encuentre que esta es la ruta más rápida para que su creación de PDF funcione bien.

Sin embargo, en muchos casos, las herramientas gratuitas funcionarán bien para usted. Si sus requisitos son muy sencillos, entonces wkhtmltopdf, o una solución básica de Chrome y Puppeteer sin interfaz gráfica puede ser la solución. Ciertamente pareció funcionar para muchas de las personas que respondieron a mi tweet original.

Sin embargo, si tiene dificultades para obtener el resultado que desea, tenga en cuenta que puede ser una limitación de la impresión del navegador y no algo que esté haciendo mal. En el caso de que desee más compatibilidad con Paged Media, pero no esté en condiciones de optar por un producto comercial, tal vez eche un vistazo a WeasyPrint.

Espero que este sea un resumen útil de las herramientas disponibles para crear archivos PDF desde su aplicación web. Por lo menos, demuestra que hay una amplia variedad de opciones, si su elección inicial no funciona bien.

Agregue sus propias experiencias y sugerencias en los comentarios, esta es una de esas cosas con las que muchos de nosotros terminamos lidiando, y la experiencia personal compartida puede ser increíblemente útil.

Otras lecturas

Un resumen de los diversos recursos y herramientas mencionados en este artículo, junto con otros recursos útiles para trabajar con archivos PDF desde aplicaciones web.

Especificaciones

  • Módulo multimedia paginado
  • Fragmentación

Artículos y recursos

  • Diseño para impresión con CSS
  • Romper cajas con fragmentación de CSS
  • Una guía sobre el estado de las hojas de estilo de impresión en 2018
  • Primeros pasos con Headless Chrome y Puppeteer
  • imprimir-css.rocks

Herramientas

  • wkhtmltopdf
  • paginado.js
  • vivlioestilo
  • Príncipe
  • casa de la antena
  • PDF Reactor
  • Doctor Raptor
  • WeasyImprimir
  • PDFMultitud
  • mPDF
  • jsPDF
  • pdfhacer
  • Servidor de producción y publicación