spiPDF : générer des contenus sur mesure en PDF

Le plugin spiPDF génère des fichiers au format PDF d’article ou de tout autre élément SPIP, simplement à partir d’un squelette construit au format HTML 4 et facile à modifier.

Avertissement de sécurité

Ce plugin a fait l’objet d’une faille de sécurité en mars 2017, il est important d’avoir son site SPIP et le plugin à jour pour continuer à utiliser ce plugin en toute sécurité

Présentation

Le plugin génère des fichiers PDF à partir d’un squelette écrit au format HTML 4.
Il vous permet donc de créer un PDF réellement sur mesure sans d’autre compétence que de connaître le HTML 4 et CSS.

Que ce soit un squelette pour vos articles, vos rubriques, votre plan de site ou d’autres éléments plus spécifiques, spiPDF génère le contenu en PDF.

Plusieurs librairies, plusieurs possibilités

Le plugin [1] se base - au choix de l’utilisateur - sur plusieurs classes de génération de PDF à partir de HTML :

Par défaut, le plugin utilise mPDF. Vous verrez plus bas dans cet article comment utilisez un autre librairie à la place.

Chacune des classes à ses avantages et ses inconvénients. On notera par exemple que mPDF gére le positionnement flottant (“float”) des éléments ce qui est indéniablement un plus pour de la génération d’article contenant des images.

N’hésitez pas à donner votre avis et vos expériences sur les différentes librairies dans les commentaires de l’article.

Pré-requis

A partir de la version v2.0.2 (compatible SPIP 4)
il est nécessaire d’avoir PHP 8.0 ou plus (pour la compatibilité avec les librairies embarquées)

Pour les versions v1.2.0 et précédentes, le plugin requiert :

  • PHP 5
  • d’installer manuellement dans le répertoire /lib/ une librairie (voir chapitre précédent)

Téléchargement et installation des librairies requises

A partir de la version v2.0.2 (compatible SPIP 4)
Il n’est plus nécessaire d’intégrer les librairies d’une facon externe, elles sont intégrées dans le répertoire vendor du plugin

Dans les anciennes versions
Vous devez les télécharger sur leurs sites respectifs et les décompresser dans un répertoire lib/ à la racine de votre site ou dans un répertoire lib/ dans le répertoire du plugin :

Les dossiers doivent se nommer exactement respectivement mpdf, html2pdf ou dompdf (sans majuscules).

Rendu obtenu avec les différentes librairies

Après un test simple de chacune des librairies, voici les résultats que j’ai obtenu :

  • mPDF version 6.0 du 01/03/2015 : bon rendu général
  • HTML2PDF version 4.03 du 27/05/2011 : rendu du texte correct, problème avec certains positionnements d’images
  • domPDF version 0.6.0 beta2 de 02/2011 : problème d’encodage des caractères

Utilisation

Une étape supplémentaire suffit pour commencer à utiliser le plugin.

Ajoutez un lien hypertexte vers le squelette du plugin, typiquement dans votre squelette article.html. Voici à quoi doit ressembler ce lien pour un article :

[<a href="[(#URL_PAGE{spipdf}
	|parametre_url{spipdf,spipdf_article}
	|parametre_url{id_article,#ID_ARTICLE}
	|parametre_url{nom_fichier,article_#ID_ARTICLE})]">
télécharger l'article au format PDF</a>]

Mise en page personnalisée

C’est tout l’intérêt du plugin : permettre une mise en page personnalisée sans connaître le PHP.

Pour obtenir un PDF sur mesure, vous pouvez :

  • soit modifier le squelette qui se trouve dans le répertoire du plugin : spipdf_article.html
  • soir créer votre propre squelette et modifier la balise #URL_PAGE pour qu’elle appelle bien votre squelette à la place de spipdf_article (remplacer spipdf_article par le nom de votre squelette)

Par exemple, vous avez dans votre répertoire squelette, un squelette plan_site_pdf.html que vous souhaitez utiliser pour générer une sortie PDF de votre plan de site.

Il vous suffira d’appeler ce squelette/PDF de la façon suivante :

[<a href="[(#URL_PAGE{spipdf}
	|parametre_url{spipdf,plan_site_pdf}
	|parametre_url{nom_fichier,plan_site_pdf})]">
télécharger le plan de site au format PDF</a>]

Ce qui donnera l’URL : http://monsite.tld/spip.php?page=spipdf&spipdf=plan_site_pdf.html

Liens vers des articles SPIP dans le PDF

Si vous utilisez des liens internes du type [->art2] dans vos articles,
il est nécessaire d’utiliser le filtre abs_url sur les balises
DESCRIPTIF, CHAPO, TEXTE, PS et NOTES pour que les liens dans votre PDF pointent bien sur votre site.

Nom de fichier personnalisé

Par défaut, les fichiers PDF se nommeront document.pdf.

Si vous souhaitez préciser un nom particulier pour votre fichier, vous devrez préciser, comme dans les exemples ci-dessus, le paramètre nom_fichier dans la balise #URL_PAGE.

Choix de la librairie de génération

Pour sélectionner l’une ou l’autre des librairies supportées, vous devez changer la valeur de l’attribut lib_pdf dans la balise du squelette spipdf_article.html ou de votre squelette personnalisé/

Les valeurs possibles sont mpdf / html2pdf / dompdf

Vous pouvez utiliser une librairie différente par type de squelette.

Format, orientation des pages et autres subtilités

Chaque librairies autorisent la mise en page directement depuis le squelette HTML mais pas de la même façon.

Pour plus de simplicité, le format (A4, A5, Letter...) est cependant gérés par le plugin depuis cette balise page pour toutes les librairies.

Pour le reste (marge, bordure, header, footer...) chaque outils à son propre fonctionnement mais tout ceci sans toucher au code du plugin.

mPDF

La librairie utilise le sélecteur CSS @page. Ceci est également explicité dans la documentation (en anglais) de la bibliothèque.

HTML2PDF

La librairie utilise les paramètres précisés via la balise (voir le squelette spipdf_article.html pour l’exemple)

Vous trouverez plus d’informations sur le wiki de la librairie et plus particulièrement sur la section concernant la fameuse balise page.

dompdf

Le support étant expérimental, je n’ai pas plus d’informations pour l’instant à fournir. A voir sur le site de cette librairie.

Contraintes et bugs connus

Certaines balises HTML peuvent ne pas être gérées par le plugin

C’est notamment le cas de balises qui ne sont pas gérées par la librairie que vous avez choisi d’utiliser. Dans ce cas, vous devriez obtenir une erreur à la génération du PDF ou un affichage dégradé. Dans cette situation, 2 solutions :

  • le HTML qui pose problème est dans votre squelette ? et bien... trouvez autre chose en attendant mieux (mais signalez-le quand même dans les commentaires)
  • le HTML est généré par SPIP ? Signalez-le dans les commentaires pour une mise à jour du plugin

Certaines balises CSS ne sont pas gérées par le plugin

Bien entendu, dans ce cas, l’affichage au format PDF sera différent de l’affichage au format HTML. On notera par exemple que le positionnement float est géré en partie par mPDF et pas du tout par HTML2PDF.

Vous devrez palier à certaines contraintes de positionnement en utilisant des tableaux imbriqués (snif !)

Encore une fois, toutes ces contraintes sont explicitées sur les site et les forums des librairies respectives.

Changer l’encodage utilisé pour la génération de PDF

Le plugin génère les PDF en UTF-8. Certaines personnes ont rencontré des problèmes de génération des contenus dans cet encodage.

Pour changer ce comportement, et utiliser ISO-8859-15, vous devez changer la constante suivante dans votre fichier d’options :

define('SPIPDF_CHARSET', 'ISO-8859-15');

Aide au développement

Pour pré-visualiser la page au lieu de générer le PDF, vous pouvez ajouter le paramètre debug_spipdf à l’URL
Par exemple : spip.php?page=spipdf&spipdf=spipdf_article&id_article=1249&nom_fichier=article-1249&debug_spipdf

Notes

[1Depuis la version 0.2.0

Discussion

96 discussions

  • 2

    Hello,
    Apparemment, pas possible de définir des header et footer pour le PDF en squelette SPIP :/ ? Quelqu’un a un exemple ?

    Répondre à ce message

  • 2

    Bonjour

    Petit curiosité je viens d’essayer d’installer le plugin ..je suis chez free, j’ai SPIP 2.17 et l’installation ne fonctionne pas, j’obtiens :

    Impossible d’activer le plugin ../plugins/auto/spipdf

    Nécessite SPIP en version [2.0.0 ;3.0.*] minimum.

    Curieux !!

    • J’ai le même problème et message sur 2.17...
      Nécessite SPIP en version [2.0.0 ;3.0.*] minimum ??

    • Bonjour,

      Effectivement, c’est curieux. Je pense qu’il faut remplacer 2.0.0 par 2.* dans plugin.xml

      Pouvez-vous essayer ?

    Répondre à ce message

  • 7

    Yves

    Peux-tu me confirmer que les paramètres de la balise <page> dans le squelette ne sont pas exploitées ? sauf la lib.

    Si oui, pourquoi ?

    • En tous cas, c’est confirmé par le code de spipdf.php.

      Pour prendre en compte les paramètres de la balise page, j’ai remplacé la ligne 258 par :

      $format_page = $GLOBALS['valeurs_page']['format']; $backtop = $GLOBALS['valeurs_page']['backtop']; $backbottom = $GLOBALS['valeurs_page']['backbottom']; $backleft = $GLOBALS['valeurs_page']['backleft']; $backright = $GLOBALS['valeurs_page']['backright'];  $margin_header = $GLOBALS['valeurs_page']['margin_header']; $margin_footer = $GLOBALS['valeurs_page']['margin_footer'];

      et la ligne 274 par :

      $mpdf = new mPDF(SPIPDF_CHARSET, $format_page, 0, "", $backleft, $backright, $backtop, $backbottom, $margin_header, $margin_footer);

      A intégrer peut-être dans une prochaine mise à jour du plugin ?

    • Il faut que je regarde plus spécifiquement mais j’avais normalement prévu le coup avec le array $possible_librairies ligne 203.

      Il doit falloir mettre ’traite_balise_page’ => false pour mpdf pour ne pas que ça passe par la fonction traite_balise_page qui supprime effectivement la balise page avant l’instanciation de la classe de génération de PDF.

      Si ça fonctionne, je changerais pour que ’traite_balise_page’ soit sur false par défaut.

    • Yves

      En tous cas, avec les modifs que j’ai faites (message plus haut), cela marche impeccable. Et je peux régler toutes les marges comme je veux.

      A l’analyse du code, il m’a semblé comprendre qu’il s’agissait d’un oubli. Alors que le constructeur de la classe mPDF peut prendre en compte ces paramètres de marge.

    • As tu essayer la modification que je t’ai indiqué ?

    • Je viens t’essayer ta proposition de modif mais cela ne marche pas.

      Normal, puisque dans la ligne 274, il manque les paramètres de marges dans le construction de classe mPDF.

    • Je pensais qu’il n’était pas nécessaire de passer les paramètres au constructeur mpdf s’ils étaient présent dans la balise page. C’est peut-être avec HTML2PDF que ça fonctionne ainsi.

      Je modifierais mon code

    • J’ai intégré les modifications ici : http://zone.spip.org/trac/spip-zone/changeset/65392

      C’est ok pour l’auteur ?

    Répondre à ce message

  • alexandre

    Bonjour,

    J’ai déjà utilisé ce plugin à plusieurs reprises mais désormais je rencontre un problème avec les images.

    C’est par contre la première fois que je teste sous SPIP3.
    J’utilise mpdf.

    Dans le pdf, les images sont remplacées par quelque chose dans ce gout là :

    %PDF-1.4 % 3 0 obj <> /Annots [ 5 0 R ] /Contents 4 0 R>> endobj 4 0 obj <> stream
    x=1 @P O1’Xˢ « tu »QpO#䃡’a > endobj 1 0 obj <> endobj 6 0 obj <> endobj 7 0 obj < /Length
    50>> stream cPΠ!Q ) Bc E jfD3 8\ ) endstream endobj 8 0 obj < /Length 156>> stream
    (c` (rɮ7/« Lh 8, .ˆȻ Vݖ ,c &Ru ?| efŦ ?kpͩ ?e( Ki ןsI/ KX »aeZV$h K Eh endstream
    endobj 2 0 obj <> /ExtGState <> /XObject <> >> endobj 9 0 obj <> endobj 10 0 obj <> endobj xref
    0 11 0000000000 65535 f 0000000774 00000 n 0000001619 00000 n 0000000015 00000 n
    0000000242 00000 n 0000000410 00000 n 0000000863 00000 n 0000000924 00000 n 0000001212
    00000 n 0000001760 00000 n 0000001883 00000 n trailer <> startxref 1993 %%EOF

    Est-ce déjà arrivé à quelqu’un ?

    Les images proviennent du champ texte, j’ai essayé plusieurs formes :

    #TEXTE
    [(#TEXTE|image_reduire500,0)]
    [(#TEXTE|abs_url|image_reduire500,0)]

    Une idée ? Une piste ?

    Répondre à ce message

  • 1

    Jusqu’à maintenant j’ai obtenu les meilleurs résultats avec tcpdf. Y a-t-il le project d’inclure ce système aussi, ou est-ce trop grand ?

    • Bonjour,

      tcpdf ne génére pas de PDF à partir de HTML. Ce qui est le cas pour les librariries mpdf, html2pdf et dompdf, utilisées par le plugin. Certaines d’ailleurs reposent sur tcpdf (html2pdf et mpdf).

    Répondre à ce message

  • Bonjour !

    Avec le code :

    <h3>#TITRE</h3>
                        <div class="texte">
                            [(#TEXTE|image_reduire{800,0})]
                        </div>
                                                                                     [(#REM) Portfolio : album d'images ]
                                <B_documents_portfolio_suite>
                                    <div id="documents_portfolio">
                                        <BOUCLE_documents_portfolio_suite(DOCUMENTS) {id_article} {mode=document}{extension IN png,jpg,gif} {par num titre, date}{doublons}{vu=non}>
                                            [(#FICHIER|image_reduire{0,800})]
                                    </BOUCLE_documents_portfolio_suite>
                                    </div><!-- #documents_portfolio -->
                                </B_documents_portfolio_suite>

    Le pdf est vide lorsqu’il y a une image dans le texte. Par contre, les images du portofolio, lorsqu’il y en a ne posent pas de problème... Avant un passage à php 5.3.3, il me semble qu’il n’y avait pas de problème... Pour info SPIP 2.1.10. Librairie mpdf

    Est ce que d’autre ont le même problème ?
    Une piste pour le résoudre ?
    Merci !.

    Répondre à ce message

  • 2
    dreline

    Je suis en train de migrer mon site vers la SPIP 3.0, je tiens à signaler qu’à première vue, spipdf 0.2 fonctionne parfaitement avec. J’ai généré quelques PDF sans soucis.

    • Ca m’intéresse beaucoup, car à première vue chez moi, non.

      Des tuyaux ?

    • dreline

      Je viens de regarder encore, et je n’ai détecté aucun soucis.

      J’ai fais la mise à jour dans le répertoire de la version 2.1.14 qui avait déjà je plugin activé, puis j’ai juste réactivé le plugin.

    Répondre à ce message

  • JAVASCRIPT dans le squelette :

    Bonjour

    J’ai un squelette spécifique pour générer mon PDF.
    Si j’insère du JAVASCRIPT dans ce squelette, est-ce que le résultat affiché sera pris en compte par le générateur de PDF ?

    Répondre à ce message

  • 3

    Conseil pour la mise en page avec mPDF :

    La gestion des FLOAT et des div imbriquées est des plus approximative. Pourtant c’est mPDF qui s’en sort le mieux.

    Idem pour les background et les border.

    Faire une mise en page, même simple devient un exercice très difficile voir impossible.

    Alors, le mieux est de tout faire avec des tableaux. Là, on arrive à positionner des blocs assez correctement.

    • Bonjour,

      Il est difficile de trouver une classe PDF qui fait tout correctement. Il faut cibler selon les usages.

      Il faut en effet s’orienter vers une mise en page très basique HTML 4 pour un rendu correct.

    • Un autre conseil : si vous rencontrez des problèmes de mise en page des images, essayez tout d’abord de neutraliser la fonction spipdf_nettoyer_html présente dans spippdf.php du plugin.

      Il suffit de mettre au début de la fonction un :
      return $html;
      Ensuite vous déplacez progressivement cette ligne dans la fonction pour activer les traitements de filtrage au fur et à mesure.

      Yves a codé cette fonction pour ces propres besoins et certains traitements ne vous conviendront peut-être pas ?
      Par exemple, les titres et descriptions d’image sont systématiquement supprimées.

      De plus, certains traitements visent à palier une insuffisance dans les librairies. Mais comme les librairies évoluent, il se peut que les traitements deviennent inutiles, voir contre-productifs.

    • Dès que j’ai un peu de temps, je coderais quelques choses de plus modulaire

      Merci pour tes retours.

    Répondre à ce message

  • 8

    Après mes petits problèmes de mise en forme de la version 0.1, je viens voir ce que donne la version 0.2 ...

    Je retombe sur les mêmes défauts, alors que je n’ai même pas installé les librairies... j’ai l’impression d’un cache qui reviens. Peux tu nous dire ou se cache le fichier pdf généré pour que je puisse le supprimer et refaire des essais propres en testant les 3 librairies.

    Pour l’install des librairies : /spip/plugins/lib/ est il un endroit correct ou il vaut mieux /spip/lib ou encore /spip/plugins/spipdf/lib. Je préfèrerais le premier si cela ne pose pas de problème (passera mieux dans ma sauvegarde).

    • Bonjour,

      Les fichiers PDF sont mis en cache de la même façon que les fichiers HTML ; dans le cache de SPIP.

      Mais il est vrai que je n’avais pas pensé à une chose : il n’y a pas de bouton « recalculer le PDF » ;)

      Donc en attendant mieux, plusieurs possibilités :

      • ajouter la balise cache dans spipdf_article.html (pas testé mais ça devrait fonctionner en théorie)
        #CACHE{0}
      • vider le cache général de spip
      • ajouter &var_mode=calcul sur le lien de génération du PDF

      Pas d’autre solutions à proposer actuellement mais je vais y réfléchir.

    • Je viens de perdre un long post d’explication de retour d’expérience ... M....
      Je reprend caaalmement et un peu plus court !

      Sur les 3 endroits que j’avais évoqué pour placer les librairies, seul /spip/lib semble fonctionner. Les deux autres emplacements me renvoient au lieu du fichier pdf, le message suivant :

      Impossible de trouver la librairie de génération de PDF mpdf. vérifiez que vous l’avez bien téléchargée et installée dans /lib

      En plaçant mes librairies ainsi : /spip/lib/mpdf j’obtiens l’ouverture d’un fichier pdf ... mais c’est une page blanche.

      Je suis en spip mutualisé et les droits sur les répertoires de librairie sont : admin.www-data 755 . Y a t’il là une partie de la difficulté ?

    • La librairie dans le répertoire /plugins/spipdf/lib/mpdf devrait en théorie fonctionner puisque je teste sur /lib et sur /plugins/spipdf/lib/mpdf

      Concernant la page blanche, on ne m’a encore pas remonté ce type de bug alors là je ne vois pas. Essaye en utilisant une autre librairie (HTML2PDF par exemple).

      Merci de préciser la version de PHP et le système d’exploitation de test.

    • Pour répondre à ta question sur les versions utilisée :
      Mon seveur en ligne est une part de chez Gandi.
      Sur mon serveur en ligne
      Phpinfo me renvoie :
      ** PHP Version 5.2.4-2ubuntu5.12
      Linux gandiaxe2 2.6.18-xenU #1 SMP Tue Nov 24 18:35:42 CET 2009 i686 **
      Cela répond il à ta question ou tu veux que je te renvoies des détails ?

      Sur mon serveur local :
      **PHP Version 5.3.2-1ubuntu4.7
      Linux montreal1 2.6.32-28-generic #55-Ubuntu SMP Mon Jan 10 21:21:01 UTC 2011 i686 **

      Je continue de tomber sur des sorties pdf avec une page vide, à partir de mon serveur en ligne.

      Par contre sur mon serveur local j’obtiens des pdf qui ont les mêmes défauts qu’avec la première version du plugin (librairrie html2pdf) . J’essaye une autre librairie, pour voir, mais le pdf reste identique. Je pousse le bouchon en cherchant l’erreur :

      <page lib_pdf="paspdf" orientation="P" format="letter" backtop="7mm" backbottom="7mm" backleft="10mm" backright="10mm">

      Me renvoie encore le même pdf, cela ne devrait pas !
      J’ai l’impression que vider le cache ne suffit pas !?!

    • Vider le cache suffit ;)

      Quand je fais mes tests, j’ajoute &var_mode=calcul sur mes liens de génération et ça fonctionne.

      Concernant la page blanche, je ne vois pas. As-tu essayé avec une autre lib ? Est-ce que ton serveur de prod affiche les erreurs d’exécution de PHP ?

      Quels sont les défauts que tu rencontres avec les PDFs ?

    • Bonjour. je viens d’installer ce plugin et je l’ai essayé avec les 3 librairies. Cela fonctionne très bien pour les petits document mais pour un document qui est censé faire 57 pages : page blanche. Le bug semble déjà connu. Cordialement.

    • précisions la version mpdf est 5.4 (15/2/12)

    • Bonjour,

      Oui, ce bug est récurrent. Pouvez-vous m’envoyer le contenu de cet article que je fasse des tests dès que possible (yvestan chez gmail)

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom