Aller au contenu
getnextpdf.com

En-têtes, pieds de page et documents multipages

Une seule page suffit rarement. Dans ce tutoriel, tu écris un document qui s’étend tout seul sur trois pages. Tu donnes aussi à chaque page un en-tête qui se répète, et un pied de page qui affiche le numéro de page.

Tu vas écrire un seul script, 01-multipage.php. Il produit un journal de voyage de trois pages sous la forme d’un fichier PDF (Portable Document Format) :

  • Les entrées du journal passent d’une page à l’autre automatiquement. Tu ne dis jamais où une page se termine ; c’est le moteur qui décide.
  • Un en-tête est une bande située en haut d’une page et qui se répète sur chaque page. Le tien affiche le titre du document.
  • Un pied de page est la bande correspondante en bas. Le tien affiche le numéro de page sous la forme 1 / 3, 2 / 3 et 3 / 3.

Tout fonctionne avec le seul paquet nextpdf/core : aucun fichier de police, aucune extension supplémentaire et aucun réseau.

Deux idées font tout le travail dans ce script.

La première est le saut de page automatique. À mesure que le moteur écrit du texte, il suit un curseur : l’endroit de la page où la prochaine ligne va se poser. setAutoPageBreak(true, margin: 25) demande au moteur de surveiller ce curseur. Lorsqu’il arrive à moins de 25 points (environ un tiers de pouce) du bord inférieur, le moteur ferme la page et en commence une nouvelle.

La seconde, ce sont les éléments fixes de la page : l’en-tête et le pied de page. Tu les décris une seule fois, avant la première page. setHeaderData() enregistre le titre et une courte description pour la bande du haut. Les appels de police et de marge choisissent le lettrage et la distance au bord de la page. Le moteur dessine ensuite ces éléments sur chaque page qu’il crée, y compris les pages qu’il ajoute de lui-même.

Crée 01-multipage.php dans le dossier de ton projet :

<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Make sure the output folder exists next to this script.
@mkdir(__DIR__ . '/out');
$document = Document::createStandalone();
$document->setTitle('NextPDF Travel Journal');
// Configure the header and footer BEFORE the first page.
// The engine repeats them on every page for you.
$document->setHeaderData(title: 'NextPDF Travel Journal', description: 'A multi-page tutorial document');
$document->setHeaderFont('helvetica', 10);
$document->setHeaderMargin(5);
$document->setFooterFont('helvetica', 8);
$document->setFooterMargin(10);
// Turn on automatic page breaks. When the text cursor gets within
// 25 points of the bottom edge, the engine starts a new page.
$document->setAutoPageBreak(true, margin: 25);
$document->addPage();
$document->setFont('helvetica', 'B', 18);
$document->cell(0, 12, 'Travel journal: three days on the coast', newLine: true);
$document->ln(5);
$days = [
1 => 'We followed the shoreline north and counted seventeen lighthouses.',
2 => 'Rain moved in before noon, so we sketched the harbor from a cafe window.',
3 => 'On the last morning the fog lifted and the whole bay turned silver.',
];
foreach ($days as $day => $highlight) {
$document->setFont('helvetica', 'B', 14);
$document->cell(0, 10, "Day {$day}", newLine: true);
$document->setFont('helvetica', '', 11);
for ($entry = 1; $entry <= 12; $entry++) {
$text = "Entry {$entry} of day {$day}. {$highlight} "
. 'The trail hugged the cliffs for most of the afternoon, and every '
. 'turn opened another view of the water. We stopped often to take '
. 'notes, compare maps, and argue happily about where to eat dinner. '
. 'By the time we reached the guesthouse, our boots were soaked and '
. 'our notebooks were full.';
$document->multiCell(0, 7, $text);
$document->ln(3);
}
$document->ln(5);
}
// Ask the engine how many pages the layout produced, then save.
$pages = $document->getNumPages();
$document->save(__DIR__ . '/out/travel-journal.pdf');
echo "Wrote out/travel-journal.pdf with {$pages} pages\n";

Lance-le avec php 01-multipage.php. Le script affiche une seule ligne :

Wrote out/travel-journal.pdf with 3 pages

Ouvre out/travel-journal.pdf et fais défiler le document. La bande de titre se trouve en haut des trois pages, et les numéros de page augmentent en bas à droite.

La boucle d’écriture ne mentionne jamais les pages. Elle écrit chaque titre de journée avec cell(), qui place une ligne dans une boîte invisible. Elle écrit les entrées avec multiCell(), qui répartit un texte long sur autant de lignes que nécessaire. Trente-six entrées ne tiennent pas sur une seule page, donc le saut de page automatique se déclenche deux fois. C’est ainsi que le journal fait exactement trois pages.

L’en-tête et le pied de page ont été configurés avant le premier appel à addPage(). Cet ordre a son importance : une page déjà dessinée ne se met pas à jour par la suite. Configure d’abord les éléments fixes, et chaque page sortira cohérente.

Tu n’as jamais dessiné le numéro de page. Le pied de page l’affiche par défaut ; tu as seulement choisi sa police et sa distance au bord de la page. Pendant qu’il écrit les pages, le moteur ne peut pas encore connaître le nombre final. Il laisse donc un espace réservé dans chaque pied de page et y inscrit le vrai total au moment où tu enregistres.

Deux petits détails complètent le script. @mkdir crée le dossier out, et le signe @ empêche PHP de se plaindre lorsque le dossier existe déjà. getNumPages() demande au moteur combien de pages la mise en page a produites, afin que le message final puisse indiquer le nombre réel.

  • Une erreur « failed to open stream » sur la ligne require signifie que le script n’a pas pu trouver vendor/autoload.php. Lance-le depuis le dossier du projet qui contient vendor/.
  • Tout tient sur une seule page et la fin du texte est coupée ? Alors les sauts de page automatiques sont désactivés. Garde la ligne setAutoPageBreak(true, margin: 25), et garde-la au-dessus de la boucle d’écriture.
  • Une famille de police mal orthographiée lève une exception qui nomme la police introuvable. Vérifie l’orthographe de helvetica, et consulte Polices et balisage pour les problèmes de police plus complexes.
  • Pour tout le reste, le centre de dépannage relie les symptômes à leurs causes, et la référence des erreurs explique les exceptions générales du moteur et comment se remettre de chacune.

Tes documents peuvent désormais atteindre n’importe quelle longueur tout en gardant une allure soignée. Dans le prochain tutoriel, tu rédiges ton contenu en HTML (Hypertext Markup Language) et tu laisses le moteur le transformer en pages.

Quand tu voudras un contrôle plus fin sur les sujets abordés aujourd’hui, deux recettes vont plus loin :