Comment créer un PDF à partir de votre application Web

Publié: 2022-03-10
Résumé rapide ↬ Il existe une grande variété de choix lorsqu'il s'agit de créer un PDF à partir d'une application Web. Dans cet article, Rachel Andrew examine les outils disponibles et partage ses recommandations pour vous aider à trouver l'outil qui vous convient le mieux.

De nombreuses applications Web ont pour exigence de donner à l'utilisateur la possibilité de télécharger quelque chose au format PDF. Dans le cas d'applications (comme les magasins de commerce électronique), ces fichiers PDF doivent être créés à l'aide de données dynamiques et être immédiatement disponibles pour l'utilisateur.

Dans cet article, j'explorerai les moyens de générer un PDF directement à partir d'une application Web à la volée. Il ne s'agit pas d'une liste exhaustive d'outils, mais je vise plutôt à démontrer les différentes approches. Si vous avez un outil préféré ou des expériences personnelles à partager, veuillez les ajouter aux commentaires ci-dessous.

Commencer avec HTML et CSS

Notre application Web est probablement déjà en train de créer un document HTML en utilisant les informations qui seront ajoutées à notre PDF. Dans le cas d'une facture, l'utilisateur peut voir les informations en ligne, puis cliquer pour télécharger un PDF pour ses dossiers. Vous créez peut-être des bordereaux d'expédition; encore une fois, l'information est déjà conservée dans le système. Vous voulez formater cela de manière agréable pour le téléchargement et l'impression. Par conséquent, un bon point de départ serait de déterminer s'il est possible d'utiliser ce code HTML et CSS pour générer une version PDF.

CSS a une spécification qui traite du CSS pour l'impression, et c'est le module Paged Media. J'ai un aperçu de cette spécification dans mon article "Concevoir pour l'impression avec CSS", et CSS est utilisé par de nombreux éditeurs de livres pour l'ensemble de leur sortie imprimée. Par conséquent, comme CSS lui-même a des spécifications pour les documents imprimés, nous devrions sûrement pouvoir l'utiliser ?

La manière la plus simple pour un utilisateur de générer un PDF est via son navigateur. En choisissant d'imprimer au format PDF plutôt que sur une imprimante, un PDF sera généré. Malheureusement, ce PDF n'est généralement pas tout à fait satisfaisant ! Pour commencer, il aura les en-têtes et les pieds de page qui sont automatiquement ajoutés lorsque vous imprimez quelque chose à partir d'une page Web. Il sera également formaté en fonction de votre feuille de style d'impression - en supposant que vous en ayez une.

Le problème que nous rencontrons ici est la mauvaise prise en charge de la spécification de fragmentation dans les navigateurs ; cela peut signifier que le contenu de vos pages se brise de manière inhabituelle. La prise en charge de la fragmentation est inégale, comme je l'ai découvert lorsque j'ai recherché mon article, "Breaking Boxes With CSS Fragmentation". Cela signifie que vous ne pourrez peut-être pas empêcher une rupture sous-optimale du contenu, les en-têtes restant le dernier élément de la page, etc.

De plus, nous n'avons pas la possibilité de contrôler le contenu des zones de marge de page, par exemple en ajoutant un en-tête de notre choix à chaque page ou numérotation des pages pour indiquer le nombre de pages d'une facture complexe. Ces éléments font partie de la spécification Paged Media, mais n'ont été implémentés dans aucun navigateur.

Mon article "Un guide sur l'état des feuilles de style d'impression en 2018" est toujours précis en termes de type de prise en charge que les navigateurs ont pour imprimer directement à partir du navigateur, à l'aide d'une feuille de style d'impression.

Plus après saut! Continuez à lire ci-dessous ↓

Impression à l'aide des moteurs de rendu du navigateur

Il existe des moyens d'imprimer au format PDF à l'aide de moteurs de rendu de navigateur, sans passer par le menu d'impression du navigateur et de se retrouver avec des en-têtes et des pieds de page comme si vous aviez imprimé le document. Les options les plus populaires en réponse à mon tweet étaient wkhtmltopdf et l'impression à l'aide de Chrome et de Puppeteer sans tête.

wkhtmltopdf

Une solution mentionnée à plusieurs reprises sur Twitter est un outil en ligne de commande appelé wkhtmltopdf. Cet outil prend un fichier HTML ou plusieurs fichiers, ainsi qu'une feuille de style et les transforme en PDF. Pour ce faire, il utilise le moteur de rendu WebKit.

Par conséquent, cet outil fait essentiellement la même chose que l'impression à partir du navigateur, cependant, vous n'obtiendrez pas les en-têtes et pieds de page ajoutés automatiquement. De ce côté positif, si vous avez une feuille de style d'impression fonctionnelle pour votre contenu, elle devrait également être bien sortie au format PDF à l'aide de cet outil, et donc une mise en page simple peut très bien s'imprimer très bien.

Malheureusement, vous rencontrerez toujours les mêmes problèmes que lors de l'impression directe à partir du navigateur Web en termes de manque de prise en charge de la spécification Paged Media et des propriétés de fragmentation, car vous imprimez toujours à l'aide d'un moteur de rendu de navigateur. Il y a quelques drapeaux que vous pouvez passer dans wkhtmltopdf afin de rajouter certaines des fonctionnalités manquantes que vous auriez par défaut en utilisant la spécification Paged Media. Cependant, cela nécessite un travail supplémentaire en plus d'écrire un bon code HTML et CSS.

Chrome sans tête

Une autre possibilité intéressante est celle d'utiliser Headless Chrome et Puppeteer pour imprimer au format PDF.

Cependant, une fois de plus, vous êtes limité par la prise en charge du navigateur pour les médias paginés et la fragmentation. Certaines options peuvent être transmises à la fonction page.pdf() . Comme avec wkhtmltopdf, ceux-ci ajoutent certaines des fonctionnalités qui seraient possibles à partir de CSS si le navigateur était pris en charge.

Il se peut que l'une de ces solutions fasse tout ce dont vous avez besoin, cependant, si vous trouvez que vous vous battez, il est probable que vous atteignez les limites de ce qui est possible avec les moteurs de rendu de navigateur actuels, et devra chercher une meilleure solution.

Polyfills JavaScript pour les médias paginés

Il y a quelques tentatives pour reproduire essentiellement la spécification Paged Media dans le navigateur à l'aide de JavaScript - créant essentiellement un Paged Media Polyfill. Cela pourrait vous donner une prise en charge des médias paginés lors de l'utilisation de Puppeteer. Jetez un œil à paged.js et Vivliostyle.

Utilisation d'un agent utilisateur d'impression

Si vous souhaitez rester avec une solution HTML et CSS, vous devez vous tourner vers un agent utilisateur (UA) conçu pour l'impression à partir de HTML et CSS, qui dispose d'une API pour générer le PDF à partir de vos fichiers. Ces agents utilisateurs implémentent la spécification Paged Media et ont une bien meilleure prise en charge des propriétés CSS Fragmentation ; cela vous donnera un meilleur contrôle sur la sortie. Les principaux choix incluent :

  • Prince
  • Antenne Maison
  • PDFRéacteur

Un UA d'impression formatera les documents à l'aide de CSS, tout comme le fait un navigateur Web. Comme pour la prise en charge de CSS par les navigateurs, vous devez consulter la documentation de ces UA pour savoir ce qu'ils prennent en charge. Par exemple, Prince (que je connais le mieux) prend en charge Flexbox mais pas CSS Grid Layout au moment de la rédaction. Lorsque vous envoyez vos pages à l'outil que vous utilisez, il s'agit généralement d'une feuille de style spécifique pour l'impression. Comme pour une feuille de style d'impression classique, les CSS que vous utilisez sur votre site ne seront pas tous adaptés à la version PDF.

La création d'une feuille de style pour ces outils est très similaire à la création d'une feuille de style d'impression normale, en prenant le type de décisions en termes d'affichage ou de masquage, peut-être en utilisant une taille de police ou des couleurs différentes. Vous pourrez alors profiter des fonctionnalités de la spécification Paged Media, en ajoutant des notes de bas de page, des numéros de page, etc.

En termes d'utilisation de ces outils depuis votre application Web, vous devrez les installer sur votre serveur (après avoir acheté une licence pour le faire, bien sûr). Le principal problème de ces outils est qu'ils sont chers. Cela dit, compte tenu de la facilité avec laquelle vous pouvez ensuite produire des documents imprimés avec eux, ils pourraient bien se rentabiliser en temps de développeur économisé.

Il est possible d'utiliser Prince via une API, sur une base de paiement par document, via un service appelé DocRaptor. Ce serait certainement un bon point de départ pour de nombreuses applications, car s'il semblait qu'il deviendrait plus rentable d'héberger la vôtre, le coût de développement de la commutation serait minime.

WeasyPrint est une alternative gratuite, qui n'est pas aussi complète que les outils ci-dessus, mais qui pourrait bien atteindre les résultats dont vous avez besoin. Il n'implémente pas entièrement tous les médias paginés, cependant, il implémente plus qu'un moteur de navigateur. Certainement, un à essayer!

D'autres outils qui prétendent prendre en charge la conversion à partir de HTML et CSS incluent PDFCrowd, qui prétend avec audace prendre en charge HTML5, CSS3 et JavaScript. Cependant, je n'ai trouvé aucun détail sur ce qui était pris en charge et si l'une des spécifications Paged Media l'était. Recevoir également une mention dans les réponses à mon tweet était mPDF.

S'éloigner du HTML et du CSS

Il existe un certain nombre d'autres solutions qui s'éloignent de l'utilisation de HTML et de CSS et vous obligent à créer une sortie spécifique pour l'outil. Quelques concurrents JavaScript sont les suivants :

  • jsPDF
  • pdffaire

Recommandations

Outre les approches basées sur JavaScript, qui vous obligeraient à créer une représentation complètement différente de votre contenu pour l'impression, la beauté de bon nombre de ces solutions réside dans le fait qu'elles sont interchangeables. Si votre solution est basée sur l'appel d'un outil de ligne de commande et sur la transmission à cet outil de votre HTML, CSS et éventuellement du JavaScript, il est assez simple de basculer entre les outils.

Au cours de la rédaction de cet article, j'ai également découvert un wrapper Python qui peut exécuter un certain nombre d'outils différents. (Notez que vous devez déjà avoir installé les outils eux-mêmes, cependant, cela pourrait être un bon moyen de tester les différents outils sur un exemple de document.)

Pour la prise en charge des médias paginés et de la fragmentation, Prince, Antenna House et PDFReactor vont sortir en tête. En tant que produits commerciaux, ils sont également accompagnés d'un support. Si vous avez un budget, des pages complexes à imprimer au format PDF et que votre limite est le temps du développeur, vous constaterez probablement qu'il s'agit de la voie la plus rapide pour que votre création PDF fonctionne correctement.

Cependant, dans de nombreux cas, les outils gratuits fonctionneront bien pour vous. Si vos besoins sont très simples, alors wkhtmltopdf, ou une solution de base sans tête pour Chrome et Puppeteer peut faire l'affaire. Cela a certainement semblé fonctionner pour de nombreuses personnes qui ont répondu à mon tweet original.

Si vous avez du mal à obtenir le résultat souhaité, sachez qu'il peut s'agir d'une limitation de l'impression du navigateur et non de quelque chose que vous faites de mal. Dans le cas où vous souhaiteriez plus de support Paged Media, mais que vous n'êtes pas en mesure d'opter pour un produit commercial, jetez peut-être un coup d'œil à WeasyPrint.

J'espère qu'il s'agit d'un tour d'horizon utile des outils disponibles pour créer des fichiers PDF à partir de votre application Web. Si rien d'autre, cela démontre qu'il existe une grande variété de choix, si votre choix initial ne fonctionne pas bien.

Veuillez ajouter vos propres expériences et suggestions dans les commentaires, c'est l'une de ces choses que beaucoup d'entre nous finissent par traiter, et l'expérience personnelle partagée peut être incroyablement utile.

Lectures complémentaires

Un tour d'horizon des diverses ressources et outils mentionnés dans cet article, ainsi que d'autres ressources utiles pour travailler avec des fichiers PDF à partir d'applications Web.

Caractéristiques

  • Module média paginé
  • Fragmentation

Articles et ressources

  • Concevoir pour l'impression avec CSS
  • Briser les boîtes avec la fragmentation CSS
  • Un guide sur l'état des feuilles de style d'impression en 2018
  • Premiers pas avec Headless Chrome et Puppeteer
  • impression-css.rocks

Outils

  • wkhtmltopdf
  • paginé.js
  • Vivliostyle
  • Prince
  • Antenne Maison
  • PDFRéacteur
  • Doc Raptor
  • WeasyPrint
  • PDFCrowd
  • mPDF
  • jsPDF
  • pdffaire
  • Serveur de production et de publication