dim, 21/06/2009 - 19:12 | Yoran   Tutoriels Drupal

Drupal, Printer et wkhtmltopdf

acroread.png

Pendant longtemps pour générer des vues PDF pour un node, il n'y avait guère d'autre solution que TCPDF ou DOMPDF, via le module PdfView ou plus récemment Printer. Aujourd'hui, il existe une nouvelle méthode native et diablement efficace utilisant le célèbre moteur webKit.

État des lieux

Sous Drupal, il existe au moins deux modules qui permettent d'obtenir la version PDF d'un contenu : pdfview et printer. Le second est plus récent, un peu plus bordélique aussi, mais propose outre le PDF, l'expédition d'un article à un ami, et une version imprimable. Ca ne se refuse pas...

Le module printer pouvait (et peut toujours d'ailleurs) être paramétré pour utiliser l'une des deux librairies PHP parmi les plus connues pour générer du PDF : DomPDF et tcpdf. Je dis les plus connues car il existe un autre projet tout jeune (et français) qui cherche à se faire une place, HTMLtoPDF.

Tout serait parfait sauf que la DOMPDF gère les accents comme il peux pour planter le reste du temps, et TCPDF ne prend pas en compte les feuilles de style. Et cerise sur le gâteau, les deux sont loin d'être des foudres de guerre... Donc en attendant de tester une éventuelle inclusion de HTMLtoPDF, le sujet est donc un peu mort du côté "pur PHP".

WebKit avec Drupal

Depuis peu, printer inclus une troisième option bien plus intéressante pour qui a la main sur son serveur, l'utilisation directe du moteur de rendu WebKit à travers l'outil wkhtmltopdf.

khtmltopdf utilise WebKit (Pour les rares qui ne le savent pas encore, il s'agit du moteur de rendu de Konqueror, Safari ou encore Google Chrome) pour un rendu visuel fidèle d'une page HTML et des ses feuilles de style, et le système d'impression de Qt4.5 pour transformer le tout en PDF. Le système fonctionne sous *nix ET sous Windows (les binaires sont fournis sur le site).

Sous *nix, Qt basant sa gestion des pixmaps sur X11, nous allons avoir en plus besoin de ce serveur pour fonctionner. Enfin, pas exactement de ce serveur, mais d'un utilitaire bien utile qui simule en mémoire le protocole X11, Xvfb. Une fois l'outil installé, le plus simple est d'en faire un lien symbolique dans la racine du module printer.

Pour ce qui est de la compilation de khtmltopdf sous linux, vous trouver toutes les informations utiles ici. Ensuite, pour Linuxiens et Windowiens, il ne reste plus qu'à déplacer (ou symlinker) le binaire khtmltopdf, lui aussi, dans à la racine du module.

Paramétrage de Printer

Pour commencer, vous devez activer (au minimum) les modules suivants :

  • Printer-friendly pages (core)
  • PDF version

Ensuite, allez dans Configuration du site, puis sur l'onglet PDF. Vous devriez alors voir apparaître en haut de la page un bouton radio avec comme libellé le chemin complet vers wkhtmltopdf. Activez ce bouton radio pour que printer utilise bien wkhtmltopdf. Ceci fait, cochez Link area pour que le lien d'impression PDF soit ajouté à ceux des contenus, puis descendez en bas de la page.

Vous avez ici les options pour wkhtmltopdf, supprimez tout ce qui s'y trouve. Ces options ne sont en effet pas compatible avec la version 0.8. Une fois la zone vidée, les Unixiens constaterons que juste en dessous se trouvent les options pour Xvfb. En effet, Printer va directement lancer lui-même le faux serveur X11 avant wkhtmltopdf, sans que vous n'ayez rien à faire de plus (pas besoin de créer un service donc).

Vous pouvez maintenant enregistrer la configuration et aller sur un contenu pour cliquer sur le lien PDF et vérifier ainsi que tout fonctionne.

Printer est un peu optimiste quant au temps de lancement de Xvfb et il arrive que ce dernier n'ai pas encore terminé son initialisation lorsque Printer lance wkhtmltopdf. Pour éviter cela, allez dans le dossier du module, et dans le fichier print_pdf.pages.inc, à la ligne 287, juste après le $xprocess = proc_open..., ajoutez la fonction sleep(1). Cela devrait largement suffire.

Conclusion

L'intégration de wkhtmltopdf à Printer est une bonne nouvelle pour la génération de PDF sous Drupal, permettant un rendu beaucoup plus propre en prenant beaucoup moins de ressources. Le seul inconvénient est que les liens ne seront pas clickables, mais en soit, ce n'est pas bien grave.

Commentaires

dsy, le sam, 04/07/2009 - 10:56

Le système fonctionne sous *nix ET sous Windows (les binaires sont fournis sur le site)

Bonjour,

Avez-vous testé wkhtmltopdf sous Windows ? Pour ma part, cela ne fonctionne pas.
En effet, il existe bien une version windows du binaire mais le module pour Drupal ne semble pas être adapté à Windows. Je n'ai pas trouvé d'appel à l'exécutable notamment.

Yoran, le sam, 04/07/2009 - 11:21

Ah pour le module j'avoue ne pas avoir fait le test, j'avais juste lancé le binaire sous Win. Le code n'est ceci dit pas très difficile à changer. Il est aussi possible de grandement le simplifié en recopiant le contenu dans un fichier temporaire et en faisant un simple appel d'exécutable sur ce fichier.

dsy, le sam, 04/07/2009 - 11:48

Ok merci pour ta réponse, je pourrais effectivement changer le code mais en lisant tes autres interventions, je vais regarder s'il est possible de "batcher" la création des PDF : un trigger à chaque publication d'une page créé un PDF avec wkhtmltopdf.
Merci pour tes tutoriaux :)

Yoran, le sam, 04/07/2009 - 11:52

Elle est intéressante ton idée, je n'y avais même pas pensé. Il y a une action Drupal qui lance un exécutable (le cas échéant ça ne doit pas être compliqué à faire) ? Avec cela, il suffirait de lancer wkhtmltopdf avec l'url de la version "print" et stoquer le tout dans un dossier accessible d'apache, du coup plus de gestion de cache... Merci, c'est une approche qui me plaît pas mal (deux modules en moins :)

Alexis (non vérifié), le lun, 03/05/2010 - 18:49

Bonjour,

 

Je travaille sur un site (encore en dév) avec Drupal 6.16 sous Windows Vista (édition familiale - on ne rit pas).

1. J'ai installé le module "printer".

2. J'ai téléchargé et installé "wkhtmltopdf".

3. J'ai copié l'exe + les DLLs dans [répertoire du module printer]/lib.

4. J'ai configuré le module "printer" en suivant ce qui est indiqué dans l'article.

5. Lorsque je consulte une page de mon site Drupal, j'ai bien l'icône "version PDF". Jusque là tout va bien.

Lorsque je clique sur le lien, je n'ai qu'un refresh de la page HTML, pas de téléchargement ou d'affichage de PDF. En faisant "enregistrer la cible sous..." (ou équivalent), j'obtiens la page html aussi.

Pouvez-vous m'éclairer ?

Par avance merci

onaircreation (non vérifié), le mar, 23/11/2010 - 19:07

J'ai le même problème que toi, j'ai essayé avec la version 0.9.9 de wkhtmlpdf et avec la version 0.8.3, ça ne change pas. Est ce que tu as trouvé la solution ?
Apparemment, cela viendrait du serveur qui empêche wkhtmlpdf de fonctionner correctement pour une question de droits

Yoran, le mar, 30/11/2010 - 11:28

Là sous Windows, je ne pourrais pas vous aider, désolé... ça fait plus de 10 ans que je ne l'utilise plus.

En revanche, sous GNU/Linux les choses se sont même fortement améliorées car wkhtml2pdf est maintenant dans tous les bons dépôts de base (ex. debian: aptitude install wkhtml2pdf xvfb et c'est bon...)

dsy, le mer, 01/12/2010 - 07:47

Bonjour,

Pour ma part, j'ai du modifié en profondeur le code du module Print pour que wkhtmltopdf fonctionne sous Windows Server grâce à des messages trouvés sur le forum du module :
http://drupal.org/project/issues/search/print

Malheureusement, ce module patché est maintenant plus difficile à gérer (mise à jour, bugs, trous de sécurité). C'est donc une mauvaise solution.

Yoran a raison de conseiller Linux car les développeurs de modules Drupal travaillent presque exclusivement sous Linux. Cela explique les incompatibilités avec Windows lors des opérations systèmes (ex: exécution de processus).

dsy

Yoran, le mer, 01/12/2010 - 08:36

Pour "print" je ne vais pas te jeter la pierre car j'ai fait exactement la même chose. J'ai un module "printer" qui doit faire 200 lignes de code à tout casser et que je colle sur toutes mes installations. "print" est de loin trop bordélique à mon goût et ne suis pas suffisamment (à mon gout toujours) les standards drupal. Moi je voulais entre-autre 1 template "print-page" et N templates "node-XXX-print" ce qui me parait plus cohérent avec le reste de Drupal. Bref, 200 lignes de code à maintenir, certes, mais bon, moins d'heures passées à débugger le bousin. Donc l'un dans l'autre ;-)

Après pour GNU/Linux, je trouve toujours plus logique d'utiliser l'OS de production comme OS de développement, et cela ne date pas du WEB. Et sur un serveur, beaucoup ont encore le bon sens de préférer un OS conçu pour cet usage. Pour le développement WEB c'est encore plus flagrant car au fond, la partie cliente se résume à éclipse et un navigateur. Tout le reste c'est du serveur pur et dur, donc autant utiliser ce pour qui c'est le métier. Maintenant je dis cela en ne cherchant à froisser aucune sensibilité technico-religieuse. Et autant pour un développeur de module, bosser sous GNU/Linux est plus que logique, autant je comprend que les thémeurs puisse se passer de leur panier de pomme. Même si, dans ce dernier cas, cela pose tout de même des problèmes (comment thémer une boutique lorsqu'on ne peut pas installer proprement les outils de payement, au hasard ;-).

Pierre-Yves Dubreucq (non vérifié), le jeu, 09/09/2010 - 00:01

Bien le bonjour,
Pour information ton lien vers l'article pour l'installation de wkhtmltopdf n'est pas fonctionnel :
http://artisan.karma-lab.net/node/1711
Merci pour l'article et bonne journée

Yoran, le sam, 25/09/2010 - 04:17

C'est corrigé, merci :)

Dgh (non vérifié), le dim, 19/09/2010 - 16:07

Bonjour, serait 'il possible de mettre en cache le pdf généré non pas grace à whktmlpdf mais grace à tcpdf par exemple ?

Yoran, le sam, 25/09/2010 - 05:29

Assez facilement oui. J'ai ajouté la snippet correspondant ici
http://arnumeral.fr/snippets/drupal/appliquer-a-tout-fichier-genere-le-p...

Nold (non vérifié), le jeu, 23/09/2010 - 16:36

Bonjour,

Désolé si je suis un peu à côté du sujet, mais je cherche un moyen d'afficher dans une node le contenu d'un fichier pdf déjà uploadé... est-ce que printer peut cela ? Ou bien existe-il un autre module qui puisse le faire ?

Merci d'avance.

Yoran, le sam, 25/09/2010 - 05:31

Là il faudrait bien plus de précisions :
* "afficher dans un node" - tu veux dire inclure dans le rendu du noeud le rendu du fichier pdf ou seulement un lien vers celui-ci ?
* "pdf déjà uploadé" - Il est attaché au noeud via Core/Upload ou CCK/filefield ?

Nold (non vérifié), le sam, 25/09/2010 - 10:26

Le fichier est uploadé via CCK/filefield et je voudrais un rendu du fichier pdf dans le rendu du noeud de manière à ne pas sortir de la page du site. Je proposerai en plus (sous le rendu du pdf par exemple) la possibilité de télécharger le pdf...

onaircreation (non vérifié), le dim, 16/01/2011 - 10:29

J'avais des problèmes pour faire fonctionner cette librairie sur ma box CentOS
En fait l'erreur que j'obtenais (Segmentation fault) m'a mis la puce à l'oreille et curieusement m'a mis un doute sur la version que j'utilisais de wkhtmltopdf ( la 0.1.0amd64). Je suis passé par un petit wget http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.10.0_rc1-static-i386.tar.lzma puis xz -d wkhtmltopdf-0.10.0_rc1-static-i386.tar.lzma et enfin tar -xvf wkhtmltopdf-0.10.0_rc1-static-i386.tar un coup de mv vers /modules/print/lib et hop, tout a fonctionné.
A moi les joies de cette superbe librairie

JayVee, le mar, 23/08/2011 - 22:35

Bonjour,

Depuis un moment deja j'essaie en vain de mettre en place la librairie wkhtmltopdf sur mon site Drupal.
J'ai suiviles differents tuto que j'ai pu trouver.
J'ai aussi essayer la methode decrite par onaircreation et helas rien à faire.

J'ai telecharger le fichier statique wkhmtltopdf10.0 et je l'ai decrompressé et placé une 1ere fois dans /sites/all/librairies et une 2eme fois dans /modules/print/lib
J'ai a chaque fois specifier dans les paramatres du module print l'ensemble du fichier à utiliser.
Et dans les deux cas j'ai le meme resultat, a savoir: lorsque j'appuie sur l'icone PDF, je vois que ma page web se met à travailler mais au final, je reste sur ma page initiale, et aucun fichier PDF n'est créé.

En jettant un coup d'oeil au tableau de bord, ce dernier m'indique: que la version n'est pas supportée et me demande de telecharger la deniere version-> alors que la version 10 est la versio la plus recente.

Je m'y perds grave avec cette bibliotheque.
Pouvez vous m'indiquer la demarche a suivre???
Car là je tourne en rond grave.

Pour infos : j'utilise drupal6.20 sur une machine virtuelle(virtual box) fedora14.

Je vous remercie d'avance pour toutes infos

Yoran, le mar, 23/08/2011 - 22:41

En fait j'ai arrêté d'utiliser le module print pour mes projets car il est gavé d'incohérence et j'ai du coup développé mon propre module de gestion de pdf via wkhtml2pdf.

Sinon j'ai regardé rapidement le code source et il semble cherche le binaire wkhtmltopdf dans le dossier "sites/all/libraries/wkhtmltopdf"

Yoran, le mar, 23/08/2011 - 22:41

En fait j'ai arrêté d'utiliser le module print pour mes projets car il est gavé d'incohérence et j'ai du coup développé mon propre module de gestion de pdf via wkhtml2pdf.

Sinon j'ai regardé rapidement le code source et il semble cherche le binaire wkhtmltopdf dans le dossier "sites/all/libraries/wkhtmltopdf"

JayVee, le mar, 23/08/2011 - 23:10

Salut et merci pour ta reponse rapide.

Concernant wkhtmltopdf, je l'ai mis aussi bien dans sites/all/librairies/wkhtmltopdf que dans sites/all/modules/print/lib
Dans les 2 cas de figure aucun resultat. Je desespere.

Par contre je ne connaissais pas wkhtml2pdf, ou peut on trouver ce module??
Est il integrable à Drupal??

Yoran, le mer, 24/08/2011 - 09:52

2=to :) J'ai juste tapé un peu vite.

Sinon attention, erreur classique entre l'anglais et l'américain, ce n'est pas librairies, mais libraries, le chemin relatif justqu'au binaire doit donc être :

sites/all/libraries/wkhtmltopdf/wkhtmltopdf

Publier un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement.
  • Les adresses de pages web et de courriels sont transformées en liens automatiquement.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
CAPTCHA
Cette question est là pour déterminer si vous êtes humain ou pas...