Home HTML / CSS Convertir du HTML en PDF avec wkhtmltopdf

Convertir du HTML en PDF avec wkhtmltopdf

  André, Architecte technique PHP 5 min 16 novembre 2015

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) :

apt-get install wkthmltopdf

Version précompilée (par exemple sous Debian Wheezy 64bits) :

wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2.1/wkhtmltox-0.12.2.1_linux-wheezy-amd64.deb
dpkg -i wkhtmltox-0.12.2.1_linux-wheezy-amd64.deb

Dans le cas où il manquerait des dépendances, la commande suivante les installera pour vous :

apt-get -f install

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 http://www.webnet.fr /tmp/webnet.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 :

wkhtmltopdf /var/www/mon_fichier.html mon_fichier.pdf

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 :


// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        new Knp\Bundle\SnappyBundle\KnpSnappyBundle(),
        //...
    );
}

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

$container->get('knp_snappy.pdf')->generate('http://www.google.fr', '/path/to/the/file.pdf');

Depuis un fichier TWIG

$this->get('knp_snappy.pdf')->generateFromHtml(
    $this->renderView('MyBundle:Foo:bar.html.twig', array('some' => $vars)),
    '/path/to/the/file.pdf'
);

Télécharger un PDF depuis un Controller

$html = $this->renderView('MyBundle:Foo:bar.html.twig', array('some' => $vars));
return new Response(
    $this->get('knp_snappy.pdf')->getOutputFromHtml($html),
    200,
    array(
        'Content-Type' => 'application/pdf',
        'Content-Disposition' => 'attachment; filename="file.pdf"'
    )
);

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 :


wkhtmltopdf cover couverturer.html table_de_matiere.html chapitre1.html chapitre2.html livre.pdf

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é:

wkhtmltopdf http://www.webnet.fr /var/tmp/webnet.ps

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.

Lire les articles similaires

Laisser un commentaire

Social Share Buttons and Icons powered by Ultimatelysocial