PDF

Manuel PHP
Précédent |  | Suivant

# LXXVI. PDF

Vous disposez de fonctions PDF en PHP pour créer des fichiers PDF, pour peu que vous ayez la bibliothèque PDF de Thomas Merz (disponible à : http://www.pdflib.com/pdflib/index.html (site anglais)). Vous aurez aussi besoin des librairies JPEG library, the TIFF library, pour compiler cette librairie. Ces deux librairies posent pas mal de problèmes lors de la configuration. Suivez attentivement les messages d'erreur.

Reportez vous à l'excellente documentation de PDFLib, disponible avec la distribution de PDFLib. C'est une introduction très pratique des possibilités de PDFLib et elle contient la liste la plus complète et les descriptions les plus à jours des fonctions.

Toutes les fonctions de PDFLib se retrouvent dans PHP sous le même nom. De même, les paramètres sont identiques. Vous devez connaître les concepts de base de PDF ou de Postscript pour utiliser efficacement ce module. Toutes les longueurs et coordonnées sont mesurées en points Postscript points. Il y a généralement 72 points PostScript par pouce, mais cela dépend en fait de la résolution d'affichage.

Il y a un autre module PHP pour créer des document PDF, basé sur la bibliothèque FastIO's's ClibPDF. Les API sont légèrement différentes. Reportez-vous à la section fonctions ClipPDF pour plus de détails.

Le module PDF introduit un nouveau type de variables. C'est `pdfdoc` : c'est un pointeur sur un document PDF et toutes les fonctions l'utilise comme premier paramètre.

# Confusion entre les vieilles versions de PDFLib

Depuis le début du support de PDF sous PHP, (commençant avec la version PDFLib 0.6), il y a eu des milliers de modifications dans les API de PDFLib. La plus part de ces modifications ont été suivies par PHP, et parfois même au prix de modifications des API PHP. Depuis la version 3.x, ces API semblent s'être stabilisées, et PHP 4 a adoptée cette version comme le minimum nécessaire pour supporter PDF. En conséquence de quoi, un grand nombre de fonction vont disparaître, ou être remplacée. Le support de PDFLib 0.6 est complétement abandonné. La liste suivante indique quelles sont les fonctions obsolètes en PHP 4.02, et qui devraient être remplacées par de nouvelles versions.

Tableau 1. Fonctions obsolètes et leur remplacements

Anciennes fonctions | Nouvelles fonctions
--- | ---
pdf_put_image() | Désormais inutile
pdf_execute_image() | Désormais inutile
pdf_get_annotation() | pdf_get_bookmark() avec les mêmes paramètres.
pdf_get_font() | pdf_get_value() avec `"font"` comme second paramètre.
pdf_get_fontsize() | pdf_get_value() avec `"fontsize"` comme second paramètre.
pdf_get_fontname() | pdf_get_parameter() avec `"fontname"` comme second paramètre.
pdf_set_info_creator() | pdf_set_info() avec `"Creator"` comme second paramètre.
pdf_set_info_title() | pdf_set_info() avec `"Title"` comme second paramètre.
pdf_set_info_subject() | pdf_set_info() avec `"Subject"` comme second paramètre.
pdf_set_info_author() | pdf_set_info() avec `"Author"` comme second paramètre.
pdf_set_info_keywords() | pdf_set_info() avec `"Keywords"` comme second paramètre.
pdf_set_leading() | pdf_set_value() avec `"leading"` comme second paramètre.
pdf_set_text_rendering() | pdf_set_value() avec `"textrendering"` comme second paramètre.
pdf_set_text_rise() | pdf_set_value() avec `"textrise"` comme second paramètre.
pdf_set_horiz_scaling() | pdf_set_value() avec `"horizscaling"` comme second paramètre.
pdf_set_text_matrix() | Désormais inutile
pdf_set_char_spacing() | pdf_set_value() avec `"charspacing"` comme second paramètre.
pdf_set_word_spacing() | pdf_set_value() avec `"wordspacing"` comme second paramètre.
pdf_set_transition() | pdf_set_parameter() avec `"transition"` comme second paramètre.
pdf_open() | pdf_new() suivi d'un appel à pdf_open_file()
pdf_set_font() | pdf_findfont() suivi d'un appel à pdf_setfont()
pdf_set_duration() | pdf_set_value() avec `"duration"` comme second paramètre.
pdf_open_gif() | pdf_open_image_file() avec `"gif"` comme second paramètre.
pdf_open_jpeg() | pdf_open_image_file() avec `"jpeg"` comme second paramètre.
pdf_open_tiff() | pdf_open_image_file() avec `"tiff"` comme second paramètre.
pdf_open_png() | pdf_open_image_file() avec `"png"` comme second paramètre.
pdf_get_imagewidth() | pdf_get_value() avec `"imagewidth"` comme second paramètre et l'image comme troisième.
pdf_get_imageheight() | pdf_get_value() avec `"imageheight"` comme second paramètre et l'image comme troisième.

# Conseils pour installer PDFLib 3.x

Depuis la version 3.0 de PDFLib vous pouvez configurer cette librairie avec l'option `--enable-shared-pdflib`.

# Choix de la version de PDFlib

Avec toutes les versions de PHP 4, ultérieure au 9 mars 2000, vous devez utiliser PDFlib 3.0 ou plus récent.

PHP 3, d'un autre coté, ne doit pas être utilisé avec une version plus récente que la 2.01. Depuis la version 1.61 du source `php3/functions/pdf.c` (php 3.19), il est possible d'utiliser la version PDFlib 3.0 ou plus récent.

# Installation des anciennes versions de PDFLib

Si vous utilisez PDFLib 2.01 vérifiez comment votre librairie a été installée. Il doit y avoir un fichier (ou un lien) vers `libpdf.so`. La version 2.01 ne fait que créer une librairie avec le nom `libpdf2.01.so` qui ne peut être trouvé lors de la compilation du programme de configuration. Vous devez créer vous même ce lien symbolique de `libpdf.so` vers `libpdf2.01.so`.

La version 2.20 de PDFLib a introduit de nombreuses modifications dans ses API, ainsi que le support des polices chinoises et japonaises. Cela impliquent malheureusement des modifications dans le module PDF de PHP 4 (mais pas de PHP 3). Si vous utilisez PDFLib 2.20, gérer correctement votre mémoire. Jusqu'à la version 3.0, PDFLib peut se révéler très instable. Le paramètre d'encodage pdf_set_font() est devenu une chaîne. Cela signifique notamment qu'il faut remplacer 4 par 'winansi'.

Si vous utilisez PDFLib 2.30, pdf_set_text_matrix() a disparu. Elle n'est plus supporté. En général, il est recommandé de consulter les notes de version de la PDFLib pour lister toutes les modifications.

A partir du 9 mars 2000, PHP 4 ne supporte plus que la version 3.0 et plus récente de PDFLib. PHP 3, par contre, ne doit pas être utilisé avec des versions plus récentes que la 2.01.

# Exemples

La plus part des fonctions sont simples d'emploi. Le plus difficile est probablement de créer un fichier PDF simple. L'exemple suivant devrait vous mettre sur les rails. Il crée un fichier `test.pdf` d'une page. La page contient du texte "Times Roman outlined", de taille de 30pt. Le texte est aussi souligné.

Exemple 1. Création d'un document PDF avec PDFLib
    <?php
    $pdf = pdf_new();
    pdf_open_file($pdf, "test.pdf");
    pdf_set_info($pdf, "Author", "Uwe Steinmann");
    pdf_set_info($pdf, "Title", "Test for PHP wrapper of PDFLib 2.0");
    pdf_set_info($pdf, "Creator", "See Author");
    pdf_set_info($pdf, "Subject", "Testing");
    pdf_begin_page($pdf, 595, 842);
    pdf_add_outline($pdf, "Page 1");
    pdf_set_font($pdf, "Times-Roman", 30, "host");
    pdf_set_value($pdf, "textrendering", 1);
    pdf_show_xy($pdf, "Times Roman outlined", 50, 750);
    pdf_moveto($pdf, 50, 740);
    pdf_lineto($pdf, 330, 740);
    pdf_stroke($pdf);
    pdf_end_page($pdf);
    pdf_close($pdf);
    pdf_delete($pdf);
    echo "<A HREF=getpdf.php>finished</A>";
    ?>
Ce script `getpdf.php` retourne simplement le document PDF.
    <?php
    $fp = fopen("test.pdf", "r");
    header("Content-type: application/pdf");
    fpassthru($fp);
    fclose($fp);
    ?>

La distribution PDFLib contient un exemple plus complexe, qui crée des pages plus élaborées, avec une horloge. Cet exemple a été converti en script PHP (vous retrouverez cet exemple dans le module clibpdf). Il utilise les possibilités de création de fichier en mémoire, sans fichier temporaire.

Exemple 2. Exemple pdfclock issue de la distribution PDFLib
    <?php
    $radius = 200;
    $margin = 20;
    $pagecount = 10;
    $pdf = pdf_new();
    if (!pdf_open_file($pdf, "")) {
        print error;
        exit;
    };
    pdf_set_parameter($pdf, "warning", "true");
    pdf_set_info($pdf, "Creator", "pdf_clock.php");
    pdf_set_info($pdf, "Author", "Uwe Steinmann");
    pdf_set_info($pdf, "Title", "Analog Clock");
    while($pagecount-- > 0) {
        pdf_begin_page($pdf, 2 * ($radius + $margin), 2 * ($radius + $margin));
        pdf_set_parameter($pdf, "transition", "wipe");
        pdf_set_value($pdf, "duration", 0.5);
        pdf_translate($pdf, $radius + $margin, $radius + $margin);
        pdf_save($pdf);
        pdf_setrgbcolor($pdf, 0.0, 0.0, 1.0);
        /* indicateurs de minutes */
        pdf_setlinewidth($pdf, 2.0);
        for ($alpha = 0; $alpha < 360; $alpha += 6) {
            pdf_rotate($pdf, 6.0);
            pdf_moveto($pdf, $radius, 0.0);
            pdf_lineto($pdf, $radius-$margin/3, 0.0);
            pdf_stroke($pdf);
        }
        pdf_restore($pdf);
        pdf_save($pdf);
        /* indicateurs de 5 minutes */
        pdf_setlinewidth($pdf, 3.0);
        for ($alpha = 0; $alpha < 360; $alpha += 30) {
            pdf_rotate($pdf, 30.0);
            pdf_moveto($pdf, $radius, 0.0);
            pdf_lineto($pdf, $radius-$margin, 0.0);
            pdf_stroke($pdf);
        }
        $ltime = getdate();
        /* aiguille des heures */
        pdf_save($pdf);
        pdf_rotate($pdf,-(($ltime['minutes']/60.0)+$ltime['hours']-3.0)*30.0);
        pdf_moveto($pdf, -$radius/10, -$radius/20);
        pdf_lineto($pdf, $radius/2, 0.0);
        pdf_lineto($pdf, -$radius/10, $radius/20);
        pdf_closepath($pdf);
        pdf_fill($pdf);
        pdf_restore($pdf);
        /* aiguille des minutes */
        pdf_save($pdf);
        pdf_rotate($pdf,-(($ltime['seconds']/60.0)+$ltime['minutes']-15.0)*6.0);
        pdf_moveto($pdf, -$radius/10, -$radius/20);
        pdf_lineto($pdf, $radius * 0.8, 0.0);
        pdf_lineto($pdf, -$radius/10, $radius/20);
        pdf_closepath($pdf);
        pdf_fill($pdf);
        pdf_restore($pdf);
        /* aiguille des secondes */
        pdf_setrgbcolor($pdf, 1.0, 0.0, 0.0);
        pdf_setlinewidth($pdf, 2);
        pdf_save($pdf);
        pdf_rotate($pdf, -(($ltime['seconds'] - 15.0) * 6.0));
        pdf_moveto($pdf, -$radius/5, 0.0);
        pdf_lineto($pdf, $radius, 0.0);
        pdf_stroke($pdf);
        pdf_restore($pdf);
        /* petit cercle au centre */
        pdf_circle($pdf, 0, 0, $radius/30);
        pdf_fill($pdf);
        pdf_restore($pdf);
        pdf_end_page($pdf);
        # pour voir une différence
        sleep(1);
    }
    pdf_close($pdf);
    $buf = pdf_get_buffer($pdf);
    $len = strlen($buf);
    header("Content-type: application/pdf");
    header("Content-Length: $len");
    header("Content-Disposition: inline; filename=foo.pdf");
    print $buf;
    pdf_delete($pdf);
    ?>

Précédent | Sommaire | Suivant
overload | Niveau supérieur | pdf_add_annotation