6.Le langage PHP

6.18.Génération de documents PDF en PHP

6.18.1.Introduction

Si vous souhaitez maîtriser totalement la mise en page de vos documents (notamment pour impression) vous serez certainement amenés à générer des documents PDF. Sachez que cela est possible en PHP notamment via l'utilisation de bibliothèques.
Sans chercher à être exhaustif sur le sujet, nous allons vous montrer comment faire avec Zend Framework. Nous vous invitons donc à installer Zend Framework[comment?].
Nous allons maintenant voir comment générer ces documents. Le principe étant de décrire le document page par page, tracé par tracé, ligne de texte par ligne de texte. Ceci peut être un peu fastidieux mais c'est le prix à payer pour un résultat maîtrisé à 100%.

6.18.2.Utilisation

L'instanciation (i.e. la création) d'un objet[c'est quoi?] représentant un document PDF se fait via l'instruction
<?php
$pdf = new Zend_Pdf();
?>
Encore faut-il que la classe Zend_Pdf soit connue. Il faut donc que la bibliothèque Zend Framework soit déclarée dans l'include_path [c'est quoi?] comme indiqué dans la procédure d'installation[comment?]. Pour cela, vous pouvez commencer le script par une ligne similaire à la suivante (que vous adapterez pour remplacer chemin_vers_zend_framework/ par le véritable chemin vers l'endroit où vous avez copié la bibliothèque Zend Framework):
<?php
set_include_path('/chemin_vers_zend_framework/library'.PATH_SEPARATOR.
                 'C:\\chemin_vers_zend_framework\\library'.PATH_SEPARATOR.
                 get_include_path());
?>
Mais comme décrit dans le chapitre include[comment faire un include?], nous préférons déclarer l'include_path dans un fichier include_path_inc.php que nous incluons en tout début de script
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/../include/include_path_inc.php');
?>
Il est alors maintenant possible d'inclure le Zend_Loader et de "charger" la classe Zend_Pdf() comme suit
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/../include/include_path_inc.php');
require_once('Zend/Loader.php');

Zend_Loader::loadClass('Zend_Pdf');
$pdf = new Zend_Pdf();
?>
Une fois le document initialisé nous pouvons y ajouter une page (ici au format A4)
<?php
Zend_Loader::loadClass('Zend_Pdf_Page');
$page1 = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);
$pdf->pages[] = $page1;
?>
Il est maintenant possible de commencer à écrire, dessiner, etc. Il faut cependant noter que les coordonnées sont déterminées en points (soit 0.0352778 cm) et par rapport au coin inférieur gauche (et non par rapport au coin supérieur gauche comme on pourrait s'y attendre). Nous allons donc mettre en place une constante CM_PT que l'on utilisera pour convertir des cm en pts.
Et pour obtenir le résultat, il y a 2 cas de figures: soit vous le sauvegardez dans un fichier
<?php
$pdf->save('monfichier.pdf');
?>
soit, s'il s'agit d'un PDF généré dans le cadre d'un site web, vous l'affichez
<?php
header('Content-Type: application/pdf');
echo $pdf->render();
?>
Exemple 1
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/../include/include_path_inc.php');
require_once('Zend/Loader.php');

define('CM_PT', 1/0.0352778); // Conversion cm en points

Zend_Loader::loadClass('Zend_Pdf');
$pdf = new Zend_Pdf();

Zend_Loader::loadClass('Zend_Pdf_Page');
$page1 = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);
$pdf->pages[] = $page1;

// Dessin d'un disque plein de 2 cm de rayon
// centre sur le point situe a 10 cm du bord gauche et a 22 cm du bas de la page
$page1->drawCircle(10*CM_PT, 22*CM_PT, 2*CM_PT);

$pdf->save(dirname(__FILE__).'/pdf_01_phpfacile.pdf');
?>
Vous trouverez le fichier généré dans le même dossier que le script
Exemple 2
Voici maintenant un exemple plus complet où vous pourrez découvrir que vous pouvez déterminer la hauteur et largeur de la page (ici $page1) en nombre de points via les methodes getHeight() et getWidth().
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/../include/include_path_inc.php');
require_once('Zend/Loader.php');

define('CM_PT', 1/0.0352778); // Conversion cm en points

Zend_Loader::loadClass('Zend_Pdf');
$pdf = new Zend_Pdf();

Zend_Loader::loadClass('Zend_Pdf_Page');
$page1 = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);
$pdf->pages[] = $page1;

// Dessin d'un disque plein de 2 cm de rayon
// centre sur le point situe a 10 cm du bord gauche et a 22 cm du bas de la page
$page1->drawCircle(10*CM_PT, 22*CM_PT, 2*CM_PT);

// Dessin d'un rectangle
$page1->drawRectangle(2*CM_PT, $page1->getHeight()-5*CM_PT,
                      $page1->getWidth()-3*CM_PT, $page1->getHeight()-10*CM_PT,
                      Zend_Pdf_Page::SHAPE_DRAW_STROKE);

Zend_Loader::loadClass('Zend_Pdf_Color_RGB');
$rouge = new Zend_Pdf_Color_RGB(1, 0, 0);
$page1->setLineColor($rouge);

$page1->setLineWidth(0.01*CM_PT);

$page1->drawLine(2*CM_PT, 25*CM_PT,
                 $page1->getWidth()-2*CM_PT, 25*CM_PT);

// Preciser une police d'ecriture est necessaire avant de pouvoir
// ecrire du texte.
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES);
$page1->setFont($font, 24); // police de 24 pts

$page1->drawText('Une ligne de texte dans la page', 2*CM_PT, 25*CM_PT);

// La couleur du texte est definie par la couleur de remplissage
// et non la couleur des lignes
$bleu = new Zend_Pdf_Color_RGB(0, 0, 1);
$page1->setFillColor($bleu);

$page1->drawText('Ce texte est en bleu', 2*CM_PT, 15*CM_PT);

//header('Content-Type: application/pdf');
//$pdf->render();
$pdf->save(dirname(__FILE__).'/pdf_02_phpfacile.pdf');
?>