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

  • 3

    Bonjour !
    J’utilise ce plugin pour réaliser une compilation d’articles. ça marche vraiment très bien. J’ai essayé de faire un sommaire et ça fonctionne sauf que le sommaire se répète pour chaque article, du coup je l’ai en plusieurs exemplaires alors que je voudrais seulement l’avoir en page 1. Est-ce que quelqu’un sait comment faire ça et pourrai me donner un petit coup de main ?
    Merci pour le plugin en tout cas.

    • Je me réponds à moi-même : j’avais conçu mon sommaire avec une boucle SPIP. Finalement, il fallait sortir ma boucle sommaire de la boucle principale pour l’afficher une seule fois. Donc ça marche.

      Seulement je m’aperçois que j’ai mal raisonné du départ car il existe une fonction INDEX avec BOOKMARKS qui permet d’afficher automatiquement un sommaire avec les liens vers les pages des articles. J’ai vu ça dans le wiki de la librairie mpdf mais je ne vois pas comment l’activer dans Spipdf.Je suppose qu’il faut ajouter quelque chose dans le fichier spipdf_fonctions.php.
      Est-ce que quelqu’un sait le faire ?

    • Bonjour,

      Je suppose qu’il faut plutôt ajouter les bookmarks dans le squelette ? http://mpdf1.com/manual/index.php?tid=118

      Dans la boucle spip qui construit votre sommaire puis dans l’article. Je dirai.

      Je n’ai pas testé ;)

    • Merci pour ce retour Yves. En fait j’ai plutôt utilisé les possibilités offertes par MPDF. J’ai bien lu la doc (c’est plutôt complet) et j’ai trouvé comment créer un index de bookmarks et un sommaire avec des ancres en introduisant quelques lignes supplémentaires dans spipdf_fonctions.php et dans ma page spipf_compil.html.
      ça marche très bien.
      MERCI pour ce plugin très utile et vraiment très puissant !

    Répondre à ce message

  • 1

    Bonjour
    Tout d’abord merci pour ce très bon plugin.
    J’ai cependant un souci. Je dois éditer un PDF contenant une carte GIS mais il se trouve que celle-ci n’apparait pas dans le PDF généré alors qu’elle apparait bien avec l’option débug activée.

    Est-ce que c’est un problème de javascript (je crois comprendre que les carte GIS sont rendues côté client) et si oui, y a-t-il un contournement possible.

    Précision, j’utilise la librairie mpdf.
    Merci pour vos éclaircissements si vous en avez.

    • Bonjour,

      Effectivement, le javascript n’est pas interprété. Je n’ai pas de solution à vous proposer hormis la génération d’une « vraie » image à la place du javascript.

    Répondre à ce message

  • 1

    Bonjour

    Merci pour ce plugin qui semble plus performant que Article-PDF

    Néanmoins, j’ai un petit souci avec les images qui se retrouvent toutes à gauche avec la première ligne du texte en bas à droite de l’image et le reste du texte en dessous, que l’image soit à gauche, au centre ou à droite dans l’article.

    Une idée pour y remédier ?

    Répondre à ce message

  • 3
    katmandou

    C’est bon j’ai trouvé, il faut rajouter dans le lien :

    |parametre_url{debug_spipdf,1}

    Par contre j’ai un autre problème, j’ai un livre à convertir en PDF, mais au bout de d’un peu plus d’une dizaine de pages, le contenu est vide !
    Je suis obligé de scinder le livre en petit chapitres, et de le convertit chapitre par chapitre.
    N’y aurait-il pas un moyen pour augmenter la taille des buffers ?

    • Ce problème est lié au preg_replace_callback trop gourmant. Mais je crois que vous l’aviez découvert seul vu mon délai de réponse ;)

    • Bonjour,

      et quelle est la solution ?
      Merci,
      Roger Burton

    • Oui, moi aussi cela m’intéresserais de savoir. J’ai une compilation d’articles à réaliser mais ils sont tous tronqués au bout de 2 ou 3 pages.... Est-ce que quelqu’un peut éclairer ma lanterne avec le preg_replace_callback ? Je n’y connais rien en PHP... Merci d’avance...

    Répondre à ce message

  • 2

    Bonsoir,

    Comment ce plugin gère les polices ?
    Si notre PDF doit utiliser une « Frutiger » par exemple, sa déclaration dans les feuilles de style suffira ?

    • Je n’ai jamais essayé mais si vous utilisez mPDF, il doit-être possible d’intégrer d’autres polices comme expliqué sur le manuel : http://mpdf1.com/manual/index.php?tid=453

    • Bonjour,

      Je serai plutôt tenté par html2pdf car il a l’air plus sympa pour la gestion des bookmark, pagehead, pagefoot, etc.
      Actuellement, dans le plugin spiPDF, je n’ai pas l’impression qu’on puisse créer les index du PDF généré. Et bien entendu, les lib supportés par le plugin ne gèrent pas la création d’index de la même façon...

    Répondre à ce message

  • 2

    bonjour

    J’ai un truc bizarre depuis un bon moment. Mais aujourd’hui, je suis bien coinçé.

    Si je remplace une image, c.a.d que je conserve le ID du document mais j’upload un nouveau fichier en remplacement, et bien j’ai bien la mise-à-jour dans la page HTML générée par SPIP, avec le squelette article.html,
    mais SPIPDF persiste à me mettre l’ancienne version de l’image.

    J’ai bien effacé /local, /tmp, le cache du navigateur, .... Rien n’y fait.

    Si j’ajoute debug_spipdf=true pour voir le code HTML généré avant la conversion en PDF, le problème est déjà présent dans le HTML. Donc cela ne vient pas de mPDF.

    J’appelle avec l’url :
    http://monsite.com/spip.php?page=spipdf_article&spipdf=spipdf_article&id_article=133&var_mode=calcul&nom_fichier=guide&debug_spipdf=true

    Donc avec cette url, j’ai l’ancienne version de l’image. NOK

    Si je remplace par page=article
    J’ai bien la nouvelle image. OK.

    Tout se passe comme si SPIPDF utilise un cache qui lui est propre ?

    • J’ai un peu progressé :

      J’ai découvert que l’anomalie est liée à la présence du filtre abs_url appelé avant le image_reduire.

      Si je le supprime, j’ai bien la dernière version de l’image.

      Maintenant, reste à comprendre pourquoi ?

    • Bonjour. Effectivement, c’est étrange mais ça doit plutôt provenir du cache image de SPIP. Car le debug_spipdf affiche le HTML de SPIP avant qu’il soit envoyé à mPDF.

    Répondre à ce message

  • 1

    Bonjour,
    Il y a un bug qui empêche de créer des pages longues (ex : chapitre d’un livre).
    En supprimant le ligne 162 du fichier spipdf_fonctions.php, le problème est réglé, mais quid des images flotantes (que j’ai remplacés pas des tableaux à cause des bugs de mpdf).

    //	$html = preg_replace_callback($patterns_float, !empty($params_pdf['float']) ? 'spipdf_remplaceSpan' : 'spipdf_remplaceSpan_wfloat', $html);
    • Bonjour,

      Oui, effectivement avec le preg_replace_callback il y un souci avec les documents longs. Je note pour corrections futures.

    Répondre à ce message

  • 1
    Teenoo

    Bonjour,

    le plugin fonctionne apparemment pour des sites en HTML4, quid des sites en HTML5 ?

    Merci :)

    • Bonjour,

      Je ne sais pas si cette question est toujours d’actualités mais voici une réponse :

      Quand l’auteur ici parle d’HTML4, ce n’est pas pour les squelettes du site mais les squelettes qui génèrent le pdf… Donc, non, pas de html 5 pour les squelettes qui génèrent les PDF mais toujours et uniquement pour le moment (selon l’avancée des librairies) en HTML4.

    Répondre à ce message

  • 1

    Bonjour,
    Ma config :
    spiPdf 0.2.4 pour spip 3.
    mpdf 5.7

    je désire afficher en mode paysage.
    J’ai modifié le source de :
    spipdf_article.html
    et remplacé dans la balise page, l’attribut orientation=« P » par orientation=« L »
    L’affichage est toujours en portrait.
    Comment faire ?
    Merci pour votre aide.
    BC

    • En regardant le code , on voit qu’en fait orientation n’est pas utilisé par le plugin, bien qu’utilisé dans l’exemple de la génération pdf d’un article.
      pour passer en mode Paysage il faut mettre -L en plus dans le format : A4-L

    Répondre à ce message

  • katmandou

    Bonjour,
    Comment afficher le résultat du pdf dans une page html pour le debug ?
    C’était possible avant, mais je ne me rappelle plus comment faire !
    Merci.

    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