Générer des PDF grâce à wkhtml avec docker

26.10.2017  • Florian Parreno

La génération de documents PDF de synthèse ou factures est régulièrement demandé par les clients. Il est toujours assez difficile d’y arriver facilement du premier coup. Entre les images à positionner, les tableaux à créer correctement et à faire rentrer sur une feuille A4 tout en utilisant du CSS relativement simple afin que le fichier soit au plus proche de ce que l’on souhaite.

Heureusement, un outil existe : wkhtmltpdpf. Il permet à partir d’une page HTML de générer un PDF convenable. Il existe sa librairie PHP associée afin de pouvoir les générer simplement.

Si vous utilisez déjà cette librairie, vous avez sans doute été confronté à une erreur avec des fichiers inaccessibles par le binaire (images ou feuilles de styles par exemple). Le document ne pourra alors plus être créé tant que ces fichiers n’auront pas été trouvés. Nous allons voir deux techniques afin de résoudre ce problème dans le contexte d’une application Symfony utilisant docker. La première en manipulant docker afin que les différents container se connaissent les uns les autres, la seconde plus simple en modifiant simplement quelques paramètres lié à Twig.

Grâce à Docker

En utilisant docker, la méthode est plus orientée serveur mais elle a le mérite de fonctionner quelle que soit la méthode que l’on utilise pour insérer des fichiers dans le pdf. Il faut faire en sorte que chaque container ait connaissance des IPs des autres et quel nom de domaine leur est associé.

Au niveau des networks, on défini les réseaux que l’on va mettre en place : leurs noms ainsi que la plage d’adresse qui sera disponible. Dans cet exemple nous avons un seul réseau : app_network sur la plage d’adresse 10.5.0.0/16. Ensuite, sur chaque container, on défini à quels réseaux il appartient, ici app_network et l’IP (fixe) que le container aura sur ce réseau. Enfin, ajoutez une configuration extra_hosts avec la liste des noms de domaine associé à une IP d’un autre container afin que celui-ci en ait connaissance. Cela aura pour effet d’ajouter une ligne dans le fichier /etc/hosts du container, ce qui lui permettra de résoudre le nom de domaine.

Ici, nous affectons l’ip 10.5.0.5 au container web, qui contient notre serveur nginx et l’ip 10.5.0.6 à notre container php, qui contient les binaires php permettant l’exécution du code. Nous donnons à ce dernier l’information qu’en cas d’accès au nom de domaine app.tld il devra aller interroger l’ip 10.5.0.5, ce qui permettra à wkhtmltopdf de résoudre les urls des images et css et de ne plus générer l’erreur comme quoi le fichier n’a pas pu être trouvé.

Grâce à Symfony

Cette technique est largement plus simple puisqu’il suffit de créer un nouveau paramètre et d’indiquer à twig quelles sont les urls de base à utiliser pour la génération des assets. Pour cette partie, nous utiliserons la même configuration docker que précédemment.

Tout d’abord, dans le fichier parameters.yml de Symfony, ajoutez un paramètre (peu importe son nom) et donnez lui la valeur du nom de votre container nginx, ici web : assets.request_context.host: web.

Puis dans le fichier config.yml, au niveau de la configuration framework, ajoutez cette configuration :

Dans vos templates twig, pensez à utiliser la fonction asset : asset('/path/to/image.jpg'). Twig sera en mesure de générer le chemin complet de l’image de la façon suivante : http://web/path/to/image.jpg. Docker sachant automatiquement résoudre les noms de ses container, le container web faisant référence à l’instance nginx, c’est le serveur nginx qui résoudra la resource, si l’image existe bien wkhtml saura insérer l’image sans souci.

Lead développeur Symfony/Angular chez Spiriit.
Couteau Suisse des technologies web, je m'adapte et trouve des solutions à des problématiques variées.
Voir l’étude de cas
Lire l’article
Lire l’actualité
En savoir plus
En savoir plus
Voir le témoignage
Fermer