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.