Aller au contenu

Créer un document multipage avec des sauts de page automatiques

Crée un document dont le contenu s’étend sur de nombreuses pages. Ajoute le contenu au fil de l’eau. Avec setAutoPageBreak() activé, le moteur de mise en page démarre une nouvelle page pour toi dès que le curseur atteint la marge inférieure. Après save(), récupère le nombre final de pages avec getNumPages(). Cette page suit examples/05-multi-page.php.

Pendant save(), le moteur écrit les instructions de chaque page dans un flux de contenu. La section §7.7.3.3 d’ISO 32000-2 définit le Contents d’une page comme un flux unique ou comme un tableau de flux concaténés dans l’ordre. Une sortie multipage est donc une suite d’objets page, et non un tampon unique.

Fenêtre de terminal
composer require nextpdf/core:^3

Aucune extension optionnelle n’est requise. Cet exemple fonctionne sur la matrice de backport PHP 8.1–8.4. getNumPages() et setAutoPageBreak() sont toutes deux stables depuis la version 1.0.0.

Un document NextPDF est un arbre de pages. À mesure que tu ajoutes du contenu, un curseur interne (getY()) avance. Lorsque les sauts de page automatiques sont actifs, le moteur vérifie l’espace vertical restant avant chaque bloc de contenu. Si le bloc ne tient pas au-dessus de la marge inférieure, le moteur finalise la page en cours et appelle addPage() pour toi. La marge inférieure que tu passes à setAutoPageBreak() est le seuil de déclenchement.

Les attributs propres à la page, comme la media box, sont héritables. La section §7.7.3.4 d’ISO 32000-2 précise qu’un attribut absent d’un objet page se résout à partir d’un nœud ancêtre de l’arbre de pages. NextPDF fixe une taille de page cohérente sur tout le document, donc chaque page générée partage la même géométrie sans que tu aies à la répéter page par page.

La surface de l’API est générée automatiquement à partir du PHPDoc. Cette page s’appuie sur ces méthodes :

  • Document::createStandalone(): self — construit un document isolé.
  • setAutoPageBreak(bool $enabled, float $margin = 20): static — active les sauts de page automatiques. $margin est le seuil de déclenchement de la marge inférieure, en millimètres.
  • addPage(?PageSize $size = null, Orientation $orientation = Orientation::Portrait): static — démarre la première page ainsi que toute page explicite.
  • multiCell(...): static / cell(...): static — émet des blocs de texte fluides ou fixes. La vérification de saut de page mesure ces blocs.
  • getNumPages(): int — le nombre de pages après la mise en page.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setAutoPageBreak(true, margin: 25);
$doc->addPage();
$doc->setFont('helvetica', '', 11);
for ($i = 1; $i <= 60; $i++) {
$doc->multiCell(0, 7, "Line {$i}: content flows until the page is full, "
. 'then the engine starts a new page automatically.');
}
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/multi-page.pdf');
echo 'Pages: ' . $doc->getNumPages() . "\n";

Voici l’exemple complet, prêt pour le harnais. Il respecte NEXTPDF_COOKBOOK_OUTPUT, que le harnais définit, et n’envoie donc pas le PDF vers STDOUT. Il ne fige lui-même aucune source d’entropie. Lorsque le harnais l’exécute, DeterministicMode fige l’horloge, /ID et la marque.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Multi-Page Document');
// Enable automatic page breaks. The 25 mm bottom margin is the trigger:
// when the cursor would cross it, the engine flushes the page and adds
// a new one before the next block is drawn.
$doc->setAutoPageBreak(true, margin: 25);
$doc->addPage();
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Multi-Page Document Example', newLine: true);
$doc->ln(5);
for ($chapter = 1; $chapter <= 3; $chapter++) {
$doc->setFont('helvetica', 'B', 14);
$doc->cell(0, 10, "Chapter {$chapter}: Lorem Ipsum", newLine: true);
$doc->setFont('helvetica', '', 11);
for ($para = 1; $para <= 5; $para++) {
$text = "Paragraph {$para} of Chapter {$chapter}. "
. 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '
. 'Sed do eiusmod tempor incididunt ut labore et dolore magna '
. 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation '
. 'ullamco laboris nisi ut aliquip ex ea commodo consequat.';
$doc->multiCell(0, 7, $text);
$doc->ln(3);
}
$doc->ln(5);
}
// The harness sets NEXTPDF_COOKBOOK_OUTPUT; honour it. STDOUT stays free
// for progress text only.
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/multi-page.pdf';
$doc->save($out);
echo 'Created multi-page.pdf with ' . $doc->getNumPages() . " pages\n";
  • Saut de page automatique désactivé. Avec setAutoPageBreak(false, …), le contenu qui dépasse la marge inférieure est rogné dans la page au lieu de s’écouler, et le document garde une seule page. Active-le pour un contenu fluide.
  • Un bloc unique plus haut que la page. Le moteur découpe en interne un multiCell dont le texte dépasse la hauteur imprimable. En revanche, un bloc unique et indivisible plus haut que la zone utilisable, par exemple une image haute, est placé une seule fois et déborde. Découpe-le toi-même.
  • Le premier addPage() reste obligatoire. cell() appelle addPage() à la demande quand aucune page n’existe. Malgré tout, appelle addPage() explicitement pour que la taille et l’orientation de la première page soient déterministes.
  • Unités de la marge. La marge de setAutoPageBreak() est exprimée en millimètres dans le système d’unités par défaut, pas en points.

getNumPages() est en O(1). Il lit un compteur et ne refait pas la mise en page. La mémoire évolue selon le contenu retenu, pas selon le nombre de pages. Le moteur émet les pages terminées vers le tampon de sortie au fur et à mesure qu’elles s’achèvent — le modèle de streaming en une seule passe (ADR-001). Le budget de 2000 ms / 64 Mo couvre des documents de quelques centaines de pages de texte sur l’hôte de référence.

Cette page n’écrit que le texte fourni par ton code. Elle n’effectue aucune analyse d’entrée, aucun accès réseau et aucune désérialisation. Traite tout texte d’origine externe comme non fiable, et borne sa longueur avant le rendu. Le moteur ne t’impose pas de limite de taille de contenu au niveau applicatif.

ÉnoncéSpécificationClausereference_id
Le Contents d’une page est un flux unique ou un tableau ordonné et concaténé de flux.ISO 32000-2§7.7.3.3
Un attribut de page héritable absent d’un objet page se résout à partir d’un nœud ancêtre de l’arbre de pages.ISO 32000-2§7.7.3.4
Le /ID du trailer est un identifiant de fichier formé de deux chaînes d’octets (requis en PDF 2.0).ISO 32000-2§7.5.5

Profil de reproductibilité — structurel (pourquoi pas au bit près). Chaque document enregistré porte un /ID de trailer dont les deux chaînes d’octets forment un identifiant de fichier (ISO 32000-2 §7.5.5, ci-dessus). Le second élément n’est pas stable d’une exécution à l’autre, donc les octets bruts diffèrent entre les exécutions même pour un contenu identique. Le harnais compare la structure normalisée par qpdf, qui retire /ID, /CreationDate et /ModDate. Cette page décrit comment NextPDF produit la structure. Elle n’affirme pas la conformité à ISO 32000-2 comme une assertion générale.

Sans objet. La composition multipage avec sauts de page automatiques est une capacité du cœur, sans verrou Premium.