Creare un documento multipagina con interruzioni automatiche di pagina
In breve
Sezione intitolata “In breve”Creare un documento con contenuti distribuiti su più pagine. Aggiungere il contenuto progressivamente. Con setAutoPageBreak() attivato, il motore di impaginazione apre automaticamente una nuova pagina quando il cursore raggiunge il margine inferiore. Dopo save(), leggere il numero finale di pagine con getNumPages(). Questa ricetta segue examples/05-multi-page.php.
Durante save(), il motore scrive il contenuto di ciascuna pagina in un flusso di contenuto. ISO 32000-2 §7.7.3.3 definisce il Contents di una pagina come un unico flusso oppure come un array di flussi concatenati in ordine. Pertanto, l’output multipagina consiste in una sequenza di oggetti pagina, non in un singolo buffer.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3Non è richiesta alcuna estensione opzionale. Questa ricetta funziona sulla matrice di backport per PHP 8.1–8.4. Sia getNumPages() sia setAutoPageBreak() sono stabili dalla versione 1.0.0.
Panoramica concettuale
Sezione intitolata “Panoramica concettuale”Un documento NextPDF è un albero di pagine. Man mano che si aggiunge contenuto, un cursore interno (getY()) avanza. Quando le interruzioni di pagina automatiche sono attive, il motore verifica lo spazio verticale residuo prima di ogni blocco di contenuto. Se il blocco non rientra al di sopra del margine inferiore, il motore completa la pagina corrente e richiama automaticamente addPage(). Il margine inferiore passato a setAutoPageBreak() è la soglia di attivazione.
Gli attributi a livello di pagina, come il media box, sono ereditabili. ISO 32000-2 §7.7.3.4 specifica che un attributo omesso da un oggetto pagina viene risolto da un nodo antenato dell’albero delle pagine. NextPDF imposta un’unica dimensione di pagina coerente per l’intero documento, perciò ogni pagina generata condivide la stessa geometria e non occorre specificarla di nuovo per ciascuna pagina.
Superficie dell’API
Sezione intitolata “Superficie dell’API”La superficie dell’API viene generata automaticamente da PHPDoc. Questa ricetta si basa sui metodi seguenti:
Document::createStandalone(): self— costruisce un documento isolato.setAutoPageBreak(bool $enabled, float $margin = 20): static— attiva le interruzioni di pagina automatiche.$marginè la soglia del margine inferiore, espressa in millimetri.addPage(?PageSize $size = null, Orientation $orientation = Orientation::Portrait): static— crea la prima pagina e qualsiasi pagina esplicita.multiCell(...): static/cell(...): static— emettono blocchi di testo a flusso o fissi. Il controllo delle interruzioni di pagina misura questi blocchi.getNumPages(): int— il numero di pagine dopo l’impaginazione.
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”<?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";Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”Questo è l’esempio completo, pronto per l’harness. Rispetta NEXTPDF_COOKBOOK_OUTPUT, impostata dall’harness, perciò non inviare il PDF su STDOUT. Non imposta entropia propria. Quando l’harness lo esegue, DeterministicMode fissa l’orologio, l’/ID e il branding.
<?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";Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Interruzione di pagina automatica disattivata. Con
setAutoPageBreak(false, …), il contenuto oltre il margine inferiore viene ritagliato nella pagina anziché proseguire, e il documento mantiene una sola pagina. Attivarla per i contenuti a flusso. - Un singolo blocco più alto della pagina. Il motore suddivide internamente una
multiCellil cui testo supera l’altezza stampabile. Tuttavia, un singolo blocco indivisibile più alto dell’area utilizzabile, ad esempio un’immagine molto alta, viene posizionato una sola volta e fuoriesce. Suddividerlo manualmente. - La prima
addPage()è comunque necessaria.cell()richiamaaddPage()su richiesta quando non esiste alcuna pagina. Ciononostante, richiamareaddPage()in modo esplicito, in modo che la dimensione e l’orientamento della prima pagina siano deterministici. - Unità del margine. Il margine di
setAutoPageBreak()è in millimetri nel sistema di unità predefinito, non in punti.
Prestazioni
Sezione intitolata “Prestazioni”getNumPages() è O(1). Legge un contatore e non riesegue l’impaginazione. L’utilizzo della memoria cresce in base al contenuto mantenuto, non al numero di pagine. Il motore scarica le pagine completate nel buffer di output non appena sono pronte — il modello di streaming a passata singola (ADR-001). Il budget di 2000 ms / 64 MB copre documenti di qualche centinaio di pagine di testo sull’host di riferimento.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”Questa ricetta scrive solo il testo fornito dal codice. Non esegue alcun parsing dell’input, alcun accesso di rete e alcuna deserializzazione. Considerare non attendibile qualsiasi testo proveniente da fonti esterne e limitarne la lunghezza prima del rendering. Il motore non impone limiti di dimensione del contenuto a livello applicativo.
Conformità
Sezione intitolata “Conformità”| Dichiarazione | Specifica | Clausola | reference_id |
|---|---|---|---|
Il Contents di una pagina è un singolo flusso oppure un array ordinato e concatenato di flussi. | ISO 32000-2 | §7.7.3.3 | |
| Un attributo di pagina ereditabile omesso da un oggetto pagina viene risolto da un nodo antenato dell’albero delle pagine. | ISO 32000-2 | §7.7.3.4 | |
Il trailer /ID è un identificatore di file composto da due stringhe di byte (obbligatorio in PDF 2.0). | ISO 32000-2 | §7.5.5 |
Profilo di riproducibilità — strutturale (perché non a livello di bit). Ogni documento salvato contiene un trailer /ID le cui due stringhe di byte costituiscono un identificatore di file (ISO 32000-2 §7.5.5, sopra). Il secondo elemento non è stabile tra le esecuzioni, perciò i byte grezzi differiscono da un’esecuzione all’altra anche a parità di contenuto. L’harness confronta la struttura normalizzata da qpdf, che rimuove /ID, /CreationDate e /ModDate. Questa ricetta descrive il modo in cui NextPDF produce la struttura. Non dichiara la conformità a ISO 32000-2 come affermazione generale.
Contesto commerciale
Sezione intitolata “Contesto commerciale”Non applicabile. La composizione multipagina con interruzioni di pagina automatiche è una funzionalità di Core, senza alcuna restrizione Premium.