Dans le cadre de nos projets, il n’est pas rare de devoir générer toutes sortes de documents PDF comme des exports sous forme de tableau, des factures, des fiches produits, et bien d’autres.
Plutôt que d’utiliser directement des librairies comme FPDF ou TPDF qui nécessite de placer chaque élément à des coordonnées précises et donc un temps important de développement, beaucoup utilisent des surcouches à ces librairies telles que HTML2PDF qui proposent de transformer directement un contenu HTML/CSS en PDF en s’abstrayant de l’écriture fastidieuse de ce code. Bien que cette librairie permette d’économiser un temps précieux de développement, elle ne gère malheureusement que peu de balises HTML et expressions CSS et ses possibilités sont donc très restreintes.
wkhtmltopdf est un outil en ligne de commande qui permet de générer un document PDF à partir d’une page HTML en utilisant le moteur de rendu QT Webkit. Il est sous licence GNU/GPL.
Au lieu de chercher à interpréter lui-même le code HTML/CSS, il délègue le traitement du rend au moteur Webkit, celui-ci va donc construire le rendu graphique de la page comme n’importe quel navigateur en gérant l’intégralité des possibilités CSS (la norme CSS3 est d’ailleurs gérée) et même en interprétant le code Javascript présent sur la page. Une fois la page rendue, c’est ce rendu qui va être transformé en fichier PDF.
Voici ce que peut faire wkhtmltopdf principalement :
- Rendu PDF fidèle de la page en interprétant le code HTML, CSS et Javascript de la page
- Impression de plus d’un document HTML dans un fichier PDF.
- Ajout d’en-têtes et pieds de page dans le fichier PDF.
- Création d’une table des matières.
- Ajout de liens dans le fichier PDF généré.
Installation de la librairie
L’installation de l’outil peut être réalisée de deux manières, soit par le gestionnaire de paquet de votre distribution, soit par une version précompilée que l’on pourra retrouver sur le site : http://wkhtmltopdf.org/downloads.html
Gestionnaire de paquet (par exemple sous Debian) :
Version précompilée (par exemple sous Debian Wheezy 64bits) :
Dans le cas où il manquerait des dépendances, la commande suivante les installera pour vous :
Voilà, rien de plus simple, vous venez d’installer l’outil et nous allons donc voir comment l’utiliser.
Utilisation en ligne de commande
La commande wkhtmltopdf doit être disponible dans votre terminal.
Essayer donc de générer un PDF :
Wkhtmltopdf utilise WebKit pour rendre la page, ce qui signifie que les fichiers PDF générés ressemblent en tout point au fichier HTML d’origine (conservation des liens cliquables, etc.).
Vous pouvez probablement déjà deviner comment convertir un fichier local :
Intégration dans Symfony2
Maintenant que la commande est disponible sur le serveur, on souhaite l’utiliser depuis PHP.
Bien que l’outil pourrait être piloté via des appels « shell_exec() », il existe déjà des librairies qui propose une approche plus objet du problème.
Si on souhaite utiliser cette librairie au sein d’un projet Symfony2, on peut par exemple utiliser le bundle KnpSnappyBundle.
Installation avec composer :
{ "require": { "knplabs/knp-snappy-bundle": "dev-master" } }
Activation de celui-ci dans le Kernel :
Configuration
# app/config/config.yml knp_snappy: pdf: enabled: true binary: /usr/local/bin/wkhtmltopdf #Chemin du binaire wkhtmltopdf options: []
Exemple d’utilisation
Depuis une page web
Depuis un fichier TWIG
Télécharger un PDF depuis un Controller
Il existe tout un tas de méthodes donc n’hésitez pas à aller jeter un œil sur la page GitHub : https://github.com/KnpLabs/KnpSnappyBundle.
Gestion des fichiers CSS et JavaScript
Concernant le CSS, 2 possibilités s’offrent à vous :
- Dans votre code HTML, vous pouvez mettre le chemin vers votre fichier CSS grâce à la balise , dans ce cas le chemin devra être le chemin absolu vers le fichier
- Utiliser l’option –user-style-sheet pour indiquer à la commande ou trouver le CSS correspondant à notre contenu HTML.
Personnellement je vous conseille la première méthode car en utilisant la seconde (avec l’option –-user-style-sheet) certains utilisateurs ont été confrontés à des comportements étranges, plusieurs tickets ont été ouvert à ce sujet.
Pour le JavaScript c’est un peu plus complexe, car le code JS met un petit temps pour s’exécuter, il faudra donc demander à wkhtmltopdf d’attendre pour générer le PDF à partir de notre rendu. On utilisera pour cela l’option –JavaScript-delay qui permettra d’indiquer un délai d’attente en millisecondes.
Aller plus loin
Pour plus de flexibilité, il existe beaucoup de commutateurs. Vous êtes en mesure de définir la taille de page du PDF (format A4 par défaut), l’orientation (portrait par défaut), dpi, les marges, les en-têtes, pieds de page, et beaucoup, beaucoup plus. Pour exploiter la pleine puissance de wkhtmltopdf, je vous recommande cette page : http://wkhtmltopdf.org/usage/wkhtmltopdf.txt
Wkhtmltopdf ne s’arrête pas à la conversion d’un seul fichier à la fois, si on le fait pointer sur plusieurs documents HTML il les combinera en un seul et unique fichier PDF. Idéal pour faire un document avec une couverture et une table des matières. Voici la commande à exécuter :
Bien que le format PDF soit le choix de sortie souhaité par la plupart d’entre vous, sachez que wkhtmltopdf peut également générer des fichiers PostScript. Il suffit de spécifier .ps comme extension de votre fichier exporté:
Chose intéressante à savoir, la librairie est accompagnée d’un autre binaire, wkhmltoimage, qui est similaire en tout point avec wkhtmltopdf mais qui permet de transformer vos pages en image (plusieurs formats sont gérés). KnpSnappyBundle permet d’ailleurs de piloter également cette librairie.