Traitement de fichiers PDF en PHP
Publié le 30/11/2011 à 11:40 dans la catégorie Programmation Web.Tags : développement, web, php, pdf.
3 commentaires.
Présentation de FPDF
FPDF est une classe PHP, distribuée librement (autorisation de modifier et redistribuer sans restriction), permettant de générer des fichiers PDF avec quelques lignes de code. Vous pouvez ainsi générer des fichiers PDF à la volée et les proposer au téléchargement directement ou de les enregistrer sur le serveur uniquement avec un peu de PHP. Un portage de cette classe existe pour plusieurs langages mais je n'y ai pas prêté plus d'attention.
Je n'ai pas connaissance de version minimale de PHP pour pouvoir l'utiliser, mais l'âge de la classe laisse supposer une version 4 minimale, peut être inférieure mais je doute que cela concerne grand monde. Nous l'utilisons sur des version 5.3+, il n'y a donc pas de soucis de compatibilité avec des versions plus récentes.
Il existe une autre solution plus complète et efficace que FPDF pour générer des PDF appelée PDFlib mais vous devez avoir la main sur le serveur car il s'agit d'un module pour PHP (ou d'un programme tiers), et celui-ci est payant (plus de 1000$). Je pense que dans la majorité des cas, FPDF suffit largement.
Téléchargement et Installation
Vous pouvez télécharger la dernière version de FPDF sur la page des téléchargements du site officiel. Décompressez le fichier récupéré dans votre espace de travail PHP. Ce fichier contient plusieurs fichiers et dossiers :
- doc, la documentation officielle (documentation des méthodes de la classe).
- font, les fichiers de polices (au format php).
- makefont, les fichiers de génération des sources de polices.
- tutorial, quelques exemples d'utilisation.
- changelog.htm, la liste des versions et les modifications apportées.
- FAQ.htm, quelques questions / réponses.
- fpdf.css, css de la FAQ.
- fpdf.php, le fichier contenant la classe FPDF.
- install.txt, les instructions d'installation.
- license.txt, la licence d'utilisation.
Pour la génération de pdf, il suffira de copier le fichier fpdf.php et le dossier font dans votre espace de travail. Nous avons pour habitude de placer ces éléments dans le dossier des classes php des sites que nous réalisons. Si vous ne comptez pas écrire de texte dans vos fichiers pdf, il est inutile de copier le dossier font.
Vous aurez besoin du contenu du dossier makefont pour la génération de polices, mais vous devriez en avoir besoin occasionnellement et rarement sur un site en production.
Pour l'utiliser, il vous suffit de faire un require() vers le fichier fpdf.php dans votre script PHP devant générer les fichiers pdf.
<?php
require('Classes/fpdf.php');
...
?>
Principe de fonctionnement
Le fonctionnement de FPDF est assez simple, les quelques lignes suivantes (issues des tutoriaux) vous permettent de créer un fichier pdf directement téléchargeable dans votre navigateur.
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World!');
$pdf->Output();
Après avoir inclus le fichier fpdf.php, la première opération consiste à ajouter une page au document. Par défaut, les pages sont au format A4, en portrait et les unités de mesure du document exprimées en millimètre. Sachez qu'il est possible de modifier le format des documents, l'orientation et les unités en précisant les nouvelles valeurs dans les paramètres du constructeur.
Avant d'écrire du texte, vous devez faire appel à la méthode SetFont() qui permet de définir la police et les styles à utiliser. Seul le nom de la police est indispensable, mais vous pouvez indiquer la taille et le style du texte par la suite. Utilisez les paramètres suivants pour formatter le texte :
- 'B', mettre le texte en gras
- 'I', mettre le texte en italique
- 'U', souligner le texte
- '', style par défaut
Ou une combinaison de ces lettres pour appliquer plusieurs styles en même temps. Pour modifier la couleur du texte, vous devez faire appel à la méthode SetTextColor() avant de l'écrire.
Pour écrire le texte, nous faisons appel à la méthode Cell() en indiquant la position de la cellule en absolue (en millimètres par défaut), suivi du texte à écrire. Les textes sont toujours écris dans une cellule, libre à vous de définir le style de cette cellule (texte centré, bordure, couleur de fond, ...) dans les paramètres de la fonction.
Après avoir saisi le contenu de votre document, il faut faire appel à la méthode Output() qui permet d'écrire le fichier, soit en le proposant directement en téléchargement dans le navigateur, soit en écrivant dans un fichier en précisant le nom de celui-ci.
$pdf->Output('mon_fichier.pdf', 'F');
Les opérations à effectuer pour créer un fichier pdf sont toujours les mêmes :
- Créer l'objet FPDF
- Ajouter une page
- Définir les propriétés de la police et les propriétés de style
- Saisie du texte
- Écrire le fichier
Il faudra répéter les opération 3 et 4 autant de fois que vous avez de textes différents à écrire. Certaines étapes pourront venir se greffer en fonction du style ou des particularités de vos documents.
Création d'une classe fille
Si vous générez des documents un minimum complexes, il sera préférable de créer une classe héritant de FPDF s'occupant de formatter le document. Pour générer les en-têtes et les pieds-de-page de vos documents, il vous sera obligatoire de procéder ainsi. Je ne m'attarde pas sur les bases de l'héritage ou de la programmation objet puisque vous utilisez des classes, je suppose que vous savez comment ça fonctionne.
Dans cet exemple, on créer une classe héritée de FPDF pour la création du Header et du Footer. Les méthodes seront appelées automatiquement à la création d'une page, qu'elle soit ajoutée par un appel à la méthode AddPage(), ou automatiquement.
require('Classes/fpdf.php');
class PDF extends FPDF{
// En-tête du document
function Header(){
$this->Image('logo.png',10,6,30); // Ajout d'une image
$this->SetFont('Arial','B',15); // Style du texte en Arial, gras, 15pt
$this->Cell(80); // Déplacement de 8cm vers la droite
$this->Cell(30,10,'Title',1,0,'C'); // Titre du document
$this->Ln(20); // Retour à la ligne
}
// Pied de page du document
function Footer(){
$this->SetY(-15); // On se place à 1.5cm du bas de la page
$this->SetFont('Arial','I',8); // Police en Arial, italique, 8pt
$this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C'); // Numéro de la page
}
}
// Création du document
$pdf = new PDF();
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->SetFont('Times');
$pdf->Cell(0,10,'Hello again !',0,1);
$pdf->Output();
Pour ajouter une image, un fait simplement appel à la méthode Image(), en indiquant le chemin vers le fichier, ses coordonnées X et Y, et sa largeur.
Comme vous pouvez le voir dans la méthode Footer(), il est possible de connaître le numéro de la page courante en faisant appel à la méthode PageNo(), et le nombre total de pages grâce à la méthode AliasNbPages() qui se chargera de remplacer {nb} dans le texte du pied de page.
On aurait pu rajouter une méthode SetTitle() à notre classe fille, qui permettrait de définir le titre du document, et bien d'autres méthodes en fonction de vos besoins.
Les exemples présents dans le dossier tutorial de FPDF reprennent pour certains ce principe d'héritage, vous devriez donc y trouver plusieurs cas si vous avez un doute sur comment hériter une classe.
Propriétés avancées
Les méthodes de FPDF ont de nombreux paramètres, souvent optionnels. Il faudra donc avoir la documentation pour vous repérer (du moins dans un premier temps). Certaines fonctionnalités vous permettent de récupérer des données concernant la pagination, de définir des metadonnées, des propriétés de styles ou d'écrire des données. La liste des fonctions et de leur paramètres étant trop importante, je vais me contenter de vous présenter celles qui me semblent les plus utiles.
Propriétés du document
- FPDF('P', 'mm', 'letter'), les pages du document seront en portrait ('L' pour paysage), les unités seront en millimètres et les document auront le format lettre. Il est possible de préciser d'autres formats tels que 'A4', 'A3' ou array(largeur, hauteur) les dimensions précisées dans l'unité que vous avez indiquée précédemment.
- SetDisplayMode('real'), le document s'affichera à sa taille réel (100%). Vous pouvez définir des valeurs de zoom en valeur numérique ou d'autres valeurs prédéfinies comme 'fullpage' ou 'fullwidth'.
- SetAutoPageBreak(true, 30), autorise la création de page automatique une fois la page précédente remplie (par défaut à true). L'intérêt est principalement de pouvoir définir la marge inférieure du document.
- SetMargins(15, 20, 15), permet de régler la marge de gauche, du haut, et de droite du document. D'autres méthodes permettent de régler les marges séparément.
Se déplacer dans le fichier
- GetX(), GetY(), vous permet de récupérer la position actuelle du curseur dans le fichier.
- SetXY(), SetX(), SetY(), vous permet de modifier la position actuelle du curseur dans le fichier.
- GetStringWidth(), retourne la largeur d'une chaîne après avoir choisi une police avec AddFont().
Écrire des données
- SetFont('Aller', '', 20, 'fonts/aller.php'), définit la police et le style du texte écrit par la suite.
- AcceptPageBreak(), fait un saut de page et retourne un booléen pour indiquer si l'opération a réussi ou non.
- AddLink(), Link(), SetLink(), permet de créer des liens vers des sites Internet ou des signets dans votre document.
- Rect(), Line(), permet de créer un rectangle et une ligne.
- MultiCell('180', '200', 'Lorem lipsum', 0, 1, 'J'), vous permet d'écrire plusieurs cellules de textes en effectuant des retours à la ligne automatiquement ou via le caractère '\n'. Ici le texte sera justifié dans le block qui aura aussi une bordure.
- Text(), Cell(), Write(), permet d'écrire du texte.
Pour la liste complète et précise des méthodes et paramètres, la doc vous aidera. Le site officiel contient également une bibliothèque de scripts utiles utilisant FPDF et d'autres ressources.
Générer ses polices
Il peut toujours être utile de pouvoir utiliser des polices en accord avec la charte graphique à utiliser pour vos document, FPDF a besoin de deux fichiers particuliers pour permettre l'utilisation d'une police non inclue par défaut. Vous pouvez générer ces fichiers soit en utilisant les scripts php disponibles dans le dossier makefont, soit directement sur Internet via cette page du site officiel.
Après avoir créé une police, vous pourrez l'utiliser dans son style de base et en souligné. Pour pouvoir l'utiliser en gras ou italique, il faudra répéter l'opération avec les fichiers .ttf de définition de la police pour chacun de ces styles. Vous devriez donc avoir 3*2 fichiers minimum pour chaque police d'écriture pour utiliser les 4 styles différents (normal, gras, italique, souligné).
Le site Internet étant simple d'utilisation, je vais me contenter de vous décrire la procédure utilisant le script présent dans le dossier makefont. Mon exemple est basé sur la police Aller.
Commencez par placer les fichiers de la police que vous souhaitez convertir dans le dossier makefont. Dans ce dossier, créez un fichier php et placez-y le code suivant en l'adaptant à votre police :
<?php
require('makefont.php'); // Script de génération de police
MakeFont('ttf/aller.ttf'); // Fichier de la police
MakeFont('ttf/allerb.ttf'); // Police en gras
?>
Accédez ensuite à ce fichier via votre navigateur. Le résultat devrait s'y afficher.
Font file compressed: aller.z
Font definition file generated: aller.php
Font file compressed: allerb.z
Font definition file generated: allerb.php
4 fichiers ont été générés, ces fichiers sont à placer dans le dossier font de FPDF.
Il ne reste plus qu'à préciser le chemin vers ces fichiers lors de l'appel à la méthode SetFont().
$pdf->SetFont('Aller', 'B', 15, 'font/allerb.php');
