Un des mes "Graals" est de trouver enfin un moyen simple rapide et fiable pour générer du PDF à partir d'un document HTML complet, avec prise en compte des feuilles de style. La raison du besoin est assez simple, j'archive tout ou presque en PDF, et particulièrement les pages WEB que j'ai peur de voir disparaître du jour au lendemain. Or avec un outil en ligne de commande, quel que soit le navigateur utilisé, j'ai toujours le moyen de créer un menu click-droit qui va bien pour convertir une page et me la ranger sagement dans le bon dossier.
Les outils libres en ligne de commande de type HTMT-to-PDF ne manque pas mais beaucoup ont tous en commun l'incapacité de prendre en charge proprement les feuilles de styles. C'est le cas par exemple d'htmtopdf et htmldoc. Ils se contentent de convertir le format HTML en son équivalent PDF et l'on y perd une grande partie de la présentation. Inacceptable.
J'en suis arrivé à la conclusion que les outils qui convertissent le mieux HTML/CSS en PDF restent définitivement les navigateurs eux-mêmes et leur système d'impression PDF comme konqueror avec le moteur de rendu KHtml/WebKit et la librairies d'impression Qt4/PDF, et FireFox avec le moteur Gecko et le système d'impression vers PDF de Gtk. Là le rendu final est propre, fidèle à la source avec quelques problèmes malgré tout : les liens ne sont pas clickables, ce qui est un peu dommage sans être rédhibitoire.
Pour ne pas embarquer tout la quincaillerie KDE, le mieux est de pouvoir utiliser directement le moteur de rendu WebKIT et la librairie PDF de QT4. Et cela tombe bien, il existe un projet wkhtmltopdf spécialement conçu pour cet usage.
Pour compiler, il faut préalablement installer le paquet libQt4WebKit-devel et procéder comme suit :
# Récupération des sourcesgaston$wget http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.8.0.tar.bz2gaston$tar -jxvf wkhtmltopdf-0.8.0.tar.bz2gaston$cd wkhtmltopdfgaston$qmake wkhtmltopdf.progaston$makegaston$Compilation du renderer
Ceci fait, le moteur est disponible et utilisable très simplement comme ceci :
gaston$./wkhtmltopdf http://artisan.karma-lab.net/print/1711 ~/Desktop/article.pdf# et un petit test...gaston$evince ~/Desktop/article.pdfgaston$Utilisation du renderer
La solution marche plutôt bien et la génération est très rapide. La seule chose qui me déplaît ici est l'utilisation de Qt.
Pour utiliser l'impression de FireFox en ligne de commande, c'est une extension qui nous vient en aide, appelée en toute logique Command Line Print. Une fois installée, cela nous donne ceci :
# génération du PDFgaston$firefox -print http://artisan.karma-lab.net/print/1711 -printmode pdf -printfile ~/Desktop/article.pdf# et un petit test...$evince ~/Desktop/article.pdfgaston$Génération de PDF à partir de firefox
Au lancement de la commande, apparaît une pop-up contenant l'article. L'impression se fait traditionnellement mais sans intervention manuelle. Le rendu visuel est nickel avec un seul "hic" : pas de fond image ou colorés...
La différence avec Qt4 est que là nous pouvons y faire quelque chose. Pour cela, vous allez éditer le fichier mininav.js de l'extension. Pour le trouver, il faut déjà se placer dans votre dossier firefox, ~/.mozilla/firefox/XXXXXX.default/extensions. Une fois dedans, fait un find -name "mininav.js" qui devrait vous indiquer le chemin. Éditez ce fichier et ajoutez le bloc suivant dans les eaux de la ligne 269, juste après les lignes que j'ai mis en commentaire :
# settings.printToFile = true
# settings.toFileName = outputFilePath(mode)
settings.printBGImages = true
settings.printBGColors = true
settings.marginLeft = 0.5
settings.marginTop = 0.5
settings.marginBottom = 0.5
settings.marginRight = 0.5
settings.unwriteableMarginLeft = 0
settings.unwriteableMarginTop = 0
settings.unwriteableMarginBottom = 0
settings.unwriteableMarginRight = 0
settings.headerStrLeft="&T"
settings.headerStrCenter=""
settings.headerStrRight=""
settings.footerStrLeft="&U"
settings.footerStrCenter=""
settings.footerStrRight=""
settings.paperWidth=280
Tant qu'à modifier l'impression, nous en profitons pour l'améliorer en redéfinissant une marge plus fine, une largeur de page compatible avec la réalité WEB, des en-têtes et pieds de page plus explicites, et aussi l'impression des images et couleurs de fond. Ceci fait, il faut tuer toutes les instances de firefox et relancer la conversion. Là vous devriez avoir un PDF pleine largeur, correctement proportionné et en tout point identique à la source. L'autre avantage de cette approche est que le javascript de la page qui éventuellement apporte des détails d'affichage, est exécuté et donc pris en compte lors de l'impression.
Quelle que soit l'outil utilisé, il aura besoin d'un serveur X11 pour fonctionner, et donc d'une variable DISPLAY correctement renseignée. Pour fonctionner "sans" serveur X11, nous allons devoir tricher et utilise le "faux" serveur Xvfb.
Xvfb est un outil fort intéressant qui offre une implémentation quasi complète du protocole X11 mais sans avoir besoin de sortie visuelle, car toutes les opérations se passent en mémoire. Utilisé avec firefox, cela donne donc ceci :
# lancement du faux serveur sur le port :10gaston$Xvfb -kb -screen 0 1280x1024x24 -dpi 96 -terminate -auth /tmp/fake_authority -nolisten tcp :10 &;# Lancement du convertisseur sur le nouveau "display"gaston$DISPLAY=:10 wkhtmltopdf http://artisan.karma-lab.net/print/1711 /home/gaston/desktop/article.pdfXlib: extension "RANDR" missing on display ":10.0".# et un petit test...gaston$evince /home/gaston/desktop/article.pdf# ménagegaston$pkill Xvfbgaston$rm -rf /tmp/fake_authoritygaston$
Nous voilà donc débarrassé du besoin d'un serveur X11 réel nous permettant d'utiliser nos deux outils sur un serveur sans écran.
Installer firefox sur un serveur ne pose en soit pas de problème. En revanche, c'est plus compliqué lorsqu'il s'agit d'installer une extension sans avoir la main sur la fenêtre. Heureusement les extensions s'installent très bien, et de manière globale (pour tous les utilisateurs, dont apache), en passant pas la ligne de commande :
root#Xvfb -kb -screen 0 1280x1024x24 -dpi 96 -terminate -auth /tmp/fake_authority -nolisten tcp :10 &root#wget http://torisugari.googlepages.com/cmdlnprint_0_4_3.xpiroot#DISPLAY=:10 firefox -install-global-extension cmdlnprint_0_4_3.xpiroot#installation en ligne de commande de l'extension
Ceci fait, il est important de ne pas laisser firefox afficher sa boite de restauration de session sous peine de se retrouver bloqué sans possibilité de clicker sur un bouton qui se trouve en mémoire. Pour cela il faut tuer toutes les instances de firefox et éditer le fichier ~/.mozilla/firefox/XXXXXXX.default/prefs.js pour y ajouter :
user_pref("browser.sessionstore.resume_from_crash", false) suppression du message de restauration de sessions
Voilà, nous avons maintenant tout l'outillage pour générer du PDF en ligne de commande, avec ou sans serveur X11. Après les usages de ces outils sont nombreux, cela peut aller de l'ajout d'un menu contextuel à votre navigateur préféré au script qui régulièrement détecte des raccourcis vers des URL et les converti en PDF. Ce n'est plus là qu'une question de besoin et d'imagination.
Salut,
tres chouette ce blog que j'ai découvert aujourd'hui. Alors, comme je suis chaud, je poste des le premier jour
Donc, et htmldoc (http://www.htmldoc.org/) ? c'est pas bien ?
Chag
Pas bien serait exagéré
En fait, à ma connaissance, il ne gère pas le CSS. D'ailleurs il ne semble pas prendre en charge non plus les URL ce qui sous-entend de télécharger localement la page avant d'effectuer le rendu. Ce qui en soi est un problème vu que je ne connais pas un seul outil en ligne de commande capable de faire proprement une copie de page AVEC éléments décrits dans une feuille CSS associée. Il y'a bien une version patchée de wget 1.10 qui traîne sensée parser les CSS liées, mais je n'ai pas réussi à obtenir un résultat valable.
Bonjour,
Et html2ps ? De mémoire, il n'utilise pas les feuilles de styles de la page demandée, mais son fichier de configuration comprend la possibilité de spécifier des instructions de mise en forme comparables aux CSS. Ce qui n'est pas mal non plus dans la mesure où on peut imposer un style d'impression à une page qui n'en comprend pas.
Et comme il peut assembler plusieurs pages en se basant sur les liens ou les balises , il n'est vraiment pas mal pour créer un document d'impression à partir de documents en lignes répartis sur de nombreuses pages. Il peut même recréer une table des matières, et si on transforme le postscript en PDF, les liens sont cliquables.
Cordialement
S'il n'utilise pas les feuilles de style, il ne répond pas mieux au cahier des charges
Excellent, c'est vrai que les convertisseurs (x)html/css vers pdf se font rare sur le net
Je ne sais pas comment tu as pu trouver celui-ci, google me retourne seulement 2 pages dont le premier résultat intéressant à tester : http://www.htmltopdf.co.uk/
Le coup du Xvfb j'avais déjà utilisé pour convertir des documents RTF via openoffice, je dois avouer que c'est quand même un peu lourd du moins pour un traitement "intensif" mais sur un serveur Web avec une couche de cache ça devient très intéressant. Merci
Yep j'avais essayé y'a longtemps mais il plante assez souvent, tient là typiquement
Encore une vilaine windowserie
Pour Xvfb, je trouve l'idée assez géniale en fait, je n'ai pas trouvé que le serveur était lent à lancer, au contraire, sinon je l'aurais collé dans un service. Du coup, ce n'est pas très lourd, même sans cache. Bon, ça ne m'empêche pas d'utiliser un cache ceci dit
Sinon, pour l'option firefox (pourquoi pas au fond) là je pense que pour un serveur, faut monter le tout en service, ou mieux, batcher la génération des pdf.
Bonjour Ulhume,
Pourrais tu donner ton secret pour mettre en place wkhtmltopdf sur drupal avec du cache.
J'utilise actuellement tcpdf, j'ai bien suivi ton tuto pour le faire fonctionner a la main, mais je cherche a present comment l'inclure en tant que "module" drupal.
Merci encore d'avance pour tes tuto !
Si cela ne pose pas de problèmes dis me moi, je te le mettais sur le dépôt.
Pas de souci Ulhume, je te suis, peux importe la méthode que tu utilise, tant que c'est la meilleur
J'ai installé xvfb en ai-je encore besoin?
Fais donc ce que tu peux, envoi ce dont j'ai besoin, si j'ai un problème ou pas je te previens
Je peux donc aussi béner le module print
Merci encore d'avance !
J'ai modifié ce tutoriel pour l'orienter sur cet usage Drupalien. Tous les sources sont dans le dépôt. Dis moi si cela se passe sans problème.
Merci beaucoup, je me repenche sur le probleme, pour l'instant je freeze des le debut...je suis en debian lenny, et pas de paquet libqt4webkit-dev a premiere vue.
Sous Lenny voilà comment je m'y suis pris: installation de qt4-qmake libwebkit-dev libqt4-core libqt4-dev libqt4-webkit qt4-qtconfig
ensuite un /usr/bin/qtconfig-qt4 et un make
Etonnant ce programme, mais tout de même c'est dommage cette dépendance a X
Moi c'est plus la dépendance à Qt qu'à X qui me casse les pieds. Avec un peu de chance, si j'arrive à la porter sur GTK, je n'aurais plus l'un ni l'autre
Je viens de tester avec le binding Gtk2 et Gtk2::MozEmbed ... et m'y suis casser les dents
Ca produit bien un PDF mais qui n'en finit pas de grossir, en fait ça part en boucle lors du $op->run (me semble que tu aais rencontré le pb). Tu n'aurais pas une petite idée ?
-----------------------------------
---------------------------
update: Tiens ? encore en poll position ?
Nan, je me suis cassé les dents pareil que toi
Du coup je vais tenter la bonne vielle méthode en C
Merci dab

Je me replonge dans l'install, pas eu le temps ce WE
Arf je ne peux pas lancer qtconfig-qt4 ? Je n'ai pas de X, enfin j'ai mis Xvfb rien y fait...
Je sais que ca fait un peu pub, mais j'ai développé ma propre lib de conversion html+css => PDF en PHP4, basé sur FPDF. Bon, elle ne comprend pas encore la totalité des balises et CSS, mais ca avance petit à petit !
Elle est téléchargeable ici : http://html2pdf.fr/
Dans ce domaine, la pub est toujours la bienvenue
Je vais tester cela dés que j'ai un peu de temps. Si ça remplace proprement domcss ça va fort m'intéresser !!
Bonjour,
Excellent tuto. Dompdf était sympa, mais trop limité. En utilisant Xvfb et firefox le résultat est bien meilleur, et ça tourne plutôt bien (dédié sous Lenny).
Seul hic, quand je gènère du pdf, j'ai un message d'erreur :
FreeFontPath: FPE "/usr/share/fonts/X11/misc" refcount is 2, should be 1; fixing.
Ca n'empêche pas le pdf de se générer, mais je préférerai réussir à ne plus avoir du tout d'erreur.
Une idée pour résoudre cela ? On en parle un peu partout sur le net, mais personne ne donne de solutions
Merci, et encore merci pour cette méthode de génération de pdf irremplaçable.
Personnellement j'obtiens une "Erreur de Segmentation" en voulant utiliser la méthode avec Command Line Print

J'ai un peu googlé pour voir si il n'y avais pas de solution mais je n'ai pas vraiment trouvé.
Es ce que quelqu'un à une solution ? ou même une idée
La raison du besoin est assez simple, j'archive tout ou presque en PDF, et particulièrement les pages WEB que j'ai peur de voir disparaître du jour au lendemain.
En effet, le web a une atroce tendance à l'amnésie mais, mieux qu'un export PDF, l'arme absolue me semble être le plug-in Scrapbook de Firefox :
https://addons.mozilla.org/fr/firefox/addon/427
Ce plug-in permet de :
- copier localement les pages HTML en intégrant le CSS, les images et tout ce qui est nécessaire au rendu de la page,
- gérer et classer les liens sur les pages sauvegardées localement,
- débarrasser les pages de leurs parties inutiles (pubs, menus et autres éléments décoratifs) pour ne conserver que l'information utile (toujours formatée),
- surligner dans une page les passages importants afin de retrouver du premier coup d'oeil les phrases et informations qui ont fait qu'on a voulu sauvegarder la page.
Debian a même créé un paquet pour Scrapbook.
Je l'utilise depuis deux ans au moins et je ne saurais plus m'en passer.
J'ai utilisé scrapbook depuis des lustres et franchement, j'ai adoré. Le seul problème c'est qu'un jour, sans crier gare, il m'a corrompu un bon volume de sauvegardes, et de manière bien aléatoire. Et la réparation n'a rien donné...
C'est depuis cette époque que je préfère l'archivage par PDF.
Le développeur de Command Line Print est venu, il y a quelques temps de cela, nous présenter une belle extension de Firefox qui fait bien son boulot : http://www.road2mayotte.org/blog/?p=2058
@+
Pour autant, ils se rassemblent autour de la ligne de commande des applications, comme des mouches autour d’une banane vieille de trois mois
J'adore ce genre de jugement de valeur, cela vaut bien mon "grands amateurs de click-click pan-pan"
pdfprint et commande line printer sont juste dédiés à des usages différents. Le monsieur semble oublier que le second permet par exemple de rajouter une impression PDF (en version click-click donc) à des navigateurs comme Epiphany. Enfin, la LC reste tout de même un peu plus pratique en mode "batch" ou sur un serveur.
http://www.princexml.com/
Un soft mentionné aujourd'hui sur Freshmeat, propriétaire malheureusement, parce que ça a l'air d'effectuer exactement ce que tu recherches.
Dis moi Ulhume, sous Drupal, est-ce que chaque version d'un document est enregistrée dans sa totalité ou seulement le différentiel avec la version précédente ?
Malheureusement c'est stocké dans une version complète.
Mouai, je me demande si les autres CMS travaillent de cette façon. Faut dire que ce n'est pas simple à gérer .. un equivalent à svn/git en base de données en quelques sortes, ça existe ça ?
(désolé mes commentaires n'ont aucun rapport avec ton article mais je n'ai pas retrouvé l'endroit ou l'on causait versionning)
En réalité faire du versionning avec un CMS simple (un e seule structure de contenu) reste jouable, en revanche lorsque tu commences à créer des contenus à géométrie variable (champs multiples, cardinalités 1-n, etc) c'est un peu plus compliqué. Ceci étant dit, ça reste jouable, mais il faudrait à ce moment là versionner plutôt des fragments de contenus (ex. le champ XXX qui est un texte) et référencer cette version sur la version du contenu lui-même.
MERCI, après avoir essayé différentes lib PHP qui ne m'ont pas convaincu, j'étais presque résolu à réinstaller une usine à gaz XSL:FO / FOP pour générer des PDF à partir de mes XML.
Grâce à cette astuce, qques lignes de PHP pour générer du HTML à partir du XML et firefox en ligne de commande pour générer les PDF : Génial !
Il me reste juste un petit soucis, je n'arrive pas à obtenir dans le PDF la même police que dans firefox.
J'ai essayé sas succès d'installer sous ma ubnutu le pacquet pour avoir les polices windaube.
A la lecture du blog de l'auteur de "Command Line Print", j'ai cru comprendre qu'il y avait une option qui pourrait peut-être convenir :
Dans pref.js il écrit :
Moi, j'ai essayé sans succès dans mininav.js :
Si qquun connait la syntaxe exacte ou une solution ...
Merci
Bonjour,
La solution d'une Capture d'Ecran avec le Logiciel FASTONE Capture avec l'option Fenêtre déroulante ne serait t'elle pas intéressante ?.
Car cela permettrait la sauvegarde de la Mise en page + CSS etc... du site Web capturé.
De plus l'exportation sous PDF se fait très simplement.
Le seul reproche étant lors de l'impression. Car je n'arrive pas à trouver un moyen de diviser ce genre de PDF "une Page" en format Multipage. Car avec les réduction de Mise à l'échelle etc... de l'imprimante j'ai toujours une impression de plus en plus petite suivant la taille "en longueur" du site.
Cordialement,
Déjà Fasttone est payant, ensuite il n'existe que sous Windows, enfin comment automatises-tu cela ?
Poster un nouveau commentaire