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

  • Bonjour,

    mon spiPDF est intégré par un inclure dans un article.html. Or même avec

    <INCLURE{fond=inclure/arboart,id_rubrique,titre=#TITRE}{id_article=#ID_ARTICLE} ></INCLURE>

    Ou

    <INCLURE{fond=inclure/arboart,id_rubrique,id_article,titre=#TITRE} ></INCLURE>

    L’id de l’article n’est pas retourné et le PDF non généré. A la place j’ai une erreur :

    Not Found
    The requested URL /construction/{id_article} was not found on this server

    Comment remédier à cela sans intégrer le code directement ? Merci

    Répondre à ce message

  • Hello :-)
    Il y a un problème dans l’article. En effet dans la colonne de droite, il y a 3 zip, alors qu’il ne devrait y en avoir qu’un...
    Il y a un zip pour la version 0.2.2 un autre pour la 0.2.3 et enfin un autre pour la 0.2.4

    Si je regarde dans :
    http://zone.spip.org/trac/spip-zone/browser/archivelist.txt#L919

    Il ne devrait y avoir un zip « que » pour la version 0.2.4
    http://zone.spip.org/trac/spip-zone/browser/_plugins_/spipdf/branches/v0.2/plugin.xml

    Surtout qu’il n’y a pas de zip « actif » qui pointe dans archivlist vers la 1.0.0 (la trunk)
    http://zone.spip.org/trac/spip-zone/browser/archivelist.txt#L920
    http://zone.spip.org/trac/spip-zone/browser/_plugins_/spipdf/trunk/paquet.xml

    Répondre à ce message

  • 2

    Bonjour

    Est ce que le plugins fonctionne actuellement chez certain ?
    Perso j’ai pas de chargement de librairie.

    Répondre à ce message

  • 4

    Bonjour,

    Sur une install en Spip 3.0.11 j’ai le message suivant avec mpdf 5.7.1
    Fatal error: Cannot redeclare array_insert() (previously declared in /httpdocs/plugins/spip-bonux-3/spip_bonux_options.php:99) in /httpdocs/lib/mpdf/includes/functions.php on line 27

    • Reynald Beaufort

      Bonjour,

      J’ai exactement le même message d’erreur lors de mes tests en local avec les mêmes versions de Spip et de mpdf

      Fatal error : Cannot redeclare array_insert() (previously declared in E :\www\te_test_v3-0-11\plugins\auto\spip_bonux\v3.0.5\spip_bonux_options.php:99) in E :\www\te_test_v3-0-11\lib\mpdf\includes\functions.php on line 27

      Quelqu’un aurait-il une solution ?
      Merci

      Reynald

    • Cela fonctionne avec mpdf 5.6

    • Reynald Beaufort

      Merci ! ça marche bien mieux avec mpdf 5.6... J’ai juste un problème pour l’intégration des images dans le texte, elle sont positionnées correctement, mais pas entourées par le texte (mais ça je crois que c’est normal c’est la librairie qui ne gère pas) , en outre, le titre et le descriptif n’apparaissent pas, et ceci, que j’utilise la balise ou . Le plugin « Insérer modèles » avec « Modèles média » est activé.

      Je continue à chercher mais si vous avez une suggestion...

      Reynald

    • Bjr

      Il suffit de renommer la fonction array_insert -> array_insert2

      -  fichier \LIB\MPDF\mpdf.php
      Line 22928 - array_insert2($textbuffer, $a1, $found+1) ;
      Line 22929 - array_insert2($textbuffer, $a2, $found+2) ;
      -  fichier \LIB\MPDF\includes\functions.php
      Line 4 - function array_insert2(&$array, $value, $offset)

    Répondre à ce message

  • Une remarque au sujet de l’utilisation de <pagebreak ></pagebreak> pour réaliser des sauts de page.
    Je ne parviens pas à faire fonctionner cette commande, en revanche en utilisant <tocpagebreak ></tocpagebreak> le saut de page fonctionne, mais il se comporte bizarrement puisqu’il introduit une page blanche sans raison apparente.

    J’ai donc modifié la ligne 220 du fichier « spipdf_fonctions.php » qui est à l’origine :
    $html = preg_replace('/<\/?page(.*)>/iUms', '', $html);

    par
    $html = preg_replace('/<\/?page>/iUms', '', $html);

    afin que <pagebreak ></pagebreak> soit reconnu.
    Cette modification est fonctionnelle et il n’y a pas le problème de la page blanche insérée par <tocpagebreak ></tocpagebreak>.

    Répondre à ce message

  • Bonjour,

    Merci pour le plugin,

    si dans un plugin, il y a un inclure, cela ne fonctionne pas.

    Quelqu’un a t’il trouvé une solution ?

    Répondre à ce message

  • 2

    Merci pour ce plugin, qui va je l’espère me permettre de prendre en compte les caractères chinois (pour l’instant je n’arrive pas encore à les afficher).

    Mon soucis est le suivant :
    Jusqu’à présent je générais mes pdf avec le plugin article_pdf.
    Avec article_pdf, mes pdf comportent dans un seul fichier toutes les découpages par page créés par le couteau suisse, alors qu’avec spipdf ce n’est pas le cas. Je retrouve dans le pdf la pagination visible sur le site, ce qui n’est pas le but.

    Je vais chercher comment régler ça, mais si vous avez une piste, je suis preneur ! :)

    • Bonjour,

      Je dirai que la piste est à chercher dans les options de la librairie PDF que vous avez choisi. Il suffit parfois d’ajouter des balises au début du squelette.

    • Merci Yves. En effet j’avais résolu le problème de pagination en échappant le traitement par l’appel d’une CSS pour le Print.
      Il me reste maintenant à arriver à afficher les caractères chinois (c’est quand même l’intérêt principal de cette librairie), chose qui semble pas tout à fait évidente.

    Répondre à ce message

  • 1

    Bonjour,

    J’ai un souci avec les formulaires qui sont générés en PDF : ils sont très beaux mais ne comportent aucune des valeurs saisies dans les champs :-(

    Y a-t-il une subtilité de paramètrages propre aux articles contenant des formulaires ?

    Voici le code de mon squelette article :

    <BOUCLE_PDF(ARTICLES){id_article}>
    <a href="[(#URL_PAGE{spipdf}
    |parametre_url{spipdf,article-pdf}
    |parametre_url{id_article,#ID_ARTICLE}
    |parametre_url{nom_fichier,Fiche-#ID_ARTICLE})]" title="télécharger le fichier PDF">PDF</a>
    </BOUCLE_PDF>

    merci pour vos conseils,
    françois

    • Bonjour,

      Je n’ai jamais essayé de générer de PDF à partir d’un formulaire mais je dirais qu’il faut pouvoir passer les valeurs saisies au squelette du PDF.

    Répondre à ce message

  • 5

    Merci pour ce plugin qui répond à un vrai besoin, mais qui m’a finalement montré qu’il y avait une faute de conception dans le code de SPIP, car devoir réécrire chaque squelette n’est pas une solution satisfaisante. Moralité, j’ai changé légèrement le code de SPIP 2.1 et je donne dans le message explicatif un code de quelques lignes qui permet la prévisualisation PDF quel que soit le squelette utilise.

    Ce petit code n’est pas aussi générique qu’il le faudrait en ce qui concerne les bibliothèques. Je n’ai par ailleurs pas vu (faute d’avoir regarder ton code) en quoi il y avait besoin de « nettoyer » le HTML produit par SPIP. Je suis par ailleurs pas satisfait de ce que donne mPDF qui semble ignorer trop de choses de mes CSS (en particulier le page-break), mais c’est peut-être faute de ne pas avoir assez lu la doc.

    • Bonjour,

      C’est intéressant ! Est-ce bien fonctionnel ? Car dans mon plugin, j’ai du ajouter des expressions régulières pour modifier à la volée du HTML généré par SPIP...

    • Bon, j’avais lu la moitié du post ;)

      c’est par exemple sur la gestion de certaines balises HTML que les librairies HTML->PDF ont du mal (exemple les <dt> <dl>).

    • Oui c’est fonctionnel, mais il faut la 2.1.22 minimum (qui par ailleurs comble un trou de sécurité donc c’est fondamental de mettre à jour ; il y a même une 2.1.23 maintenant).

      Par ailleurs le dernier message est illisible, il faut utiliser la balise « code » ou transcoder soi-même les chevrons ouvrants avec &lt; pour rendre un source Html lisible.

    • Ah oui ! je disais donc les <dl> et les <dt> posent (posaient ?) problème

    • Perso je n’utilise pas Dl et Dt mais rien n’empêche de rajouter un pré-traitement dans la fonction de prévisualisation que je donne dans l’envoi cité en référence. Mon impression est que ce plugin mériterait une nouvelle version (précisant que son intervalle de compatibilité commence avec la 2.1.22) ne comportant plus aucun squelette mais seulement la fonction dont je parle enrichie des nettoyages nécessaires s’il en reste.

      Depuis mon premier message je n’ai pas pu regarder plus avant mPdf, en particulier j’aurais voulu forcer d’entrée un affichage à 4 pages par feuille, mais il ne m’a pas semblé qu’il avait cette fonctionnalité. Je suis preneur de toute piste, avec mPdf ou autre.

    Répondre à ce message

  • 4
    le cancre

    Bonjour,

    La génération du PDF pose problème lorsque j’ai <imgXX|center>, et fonctionne lorsque j’ai <docXX|center>.
    Je me résous donc à utiliser le second, pas de souci. Seulement, je ne parviens pas à faire afficher le titre/la légende de l’image. Elle apparaît sur le site, mais pas sur le fichier généré.

    Je me dis donc qu’il s’agit d’une modification que je dois apporter au squelette.
    Avez-vous une idée de ce qu’il faudrait que je modifie dans le squelette de spipdf_artcle.html pour que les légendes s’affichent lorsque j’ai <docXX|center> ?

    Merci par avance pour vos lumières.

    BM

    • le cancre

      Personne n’a d’idée :-( ? Même une piste ?
      Merci par avance
      BM

    • Bonjour,

      Quel est précisement le souci avec <imgXX|center> ?

    • le cancre

      Bonjour,
      Oui, pardon, c’est vrai que je nai pas précisé. Je l’exposais en réponse à un post précédent de Chris.

      Parfois - ce n’est pas systématique -, le PDF généré n’affiche pas certaines images et une partie du texte. Je ne comprends pas pourquoi. Lorsque je remplace, dans les articles incriminés, <imgXX|center> par <docXX|center>, le PDF généré est impeccable.
      Impeccable sauf que je ne parviens pas à faire afficher le titre et la description de l’image (sur le site, elle est affichée automatiquement sous le document/image).

      MAIS, parce qu’il y a un « mais », c’est à n’y rien comprendre, je viens de tenter de reproduire le bug sur un article en ligne, pour que vous puissiez visualiser... eh bien cela fonctionne désormais. Je n’ai pourtant rien modifié du code... A priori donc, c’est résolu sans que je ne comprenne trop pourquoi...

      Merci à vous en tout cas de vous être penché sur mon problème, cela aura eu l’effet de tester à nouveau pour m’apercevoir que cela fonctionne désormais.

      BM

    • Tant mieux si ça fonctionne. Il y a effectivement des problèmes erratiques avec la génération du PDF via le code généré par SPIP.

    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