Impaginare una tabella HTML di grandi dimensioni su più pagine
In sintesi
Sezione intitolata “In sintesi”Passare un’unica <table> di grandi dimensioni a writeHtml(). Il motore la impagina su tutte le pagine PDF necessarie a contenere le righe. Il <thead> si ripete all’inizio di ogni pagina, così ogni pagina si presenta come una tabella completa. Questa ricetta esegue il rendering di un report di 91 righe distribuito su più pagine. Non occorre suddividere la tabella né calcolare le interruzioni di pagina.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/corePanoramica concettuale
Sezione intitolata “Panoramica concettuale”Quando una tabella è più alta di una pagina, mantenerla come unico elemento <table>. Il motore misura ciascuna riga, riempie l’altezza utile della pagina, apre una nuova pagina e continua la stessa tabella. Le righe del <thead> vengono renderizzate di nuovo all’inizio di ogni pagina di continuazione. Le pagine di continuazione mantengono i margini superiore e inferiore del documento, quindi la prima riga di una nuova pagina inizia sotto il margine superiore, non sul bordo della pagina.
Inserire le celle di intestazione in un <thead> e le righe di dati in un <tbody>. Solo il <thead> viene ripetuto. Ogni riga deve restare suddivisibile. Una singola riga più alta dell’altezza utile della pagina non può essere impaginata e genera UnsplittableContentException.
Superficie API
Sezione intitolata “Superficie API”| Simbolo | Posizione | Ruolo |
|---|---|---|
Document::writeHtml(string $html): static | NextPDF\Core\Concerns\HasTextOutput | Esegue il rendering dell’HTML e impagina le tabelle quando necessario. |
Document::createStandalone(): self | NextPDF\Core\Document | Crea un documento autonomo. |
Document::addPage(): static | NextPDF\Core\Document | Apre la prima pagina e imposta le dimensioni della pagina e i margini. |
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;
$rows = '';for ($i = 1; $i <= 91; $i++) { $rows .= "<tr><td>{$i}</td><td>Item {$i}</td><td>In stock</td></tr>";}
$doc = Document::createStandalone();$doc->addPage();$doc->writeHtml( '<table>' . '<thead><tr><th>#</th><th>Name</th><th>Status</th></tr></thead>' . "<tbody>{$rows}</tbody>" . '</table>');$doc->save(__DIR__ . '/large-table.pdf');Le 91 righe vengono distribuite su più pagine e l’intestazione #/Name/Status si ripete su ciascuna pagina.
Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”Questo esempio autonomo applica uno stile all’intestazione, alterna i colori delle righe e scrive il PDF nel percorso fornito dall’harness.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$rows = '';for ($i = 1; $i <= 91; $i++) { $bg = $i % 2 === 0 ? '#F8FAFC' : '#FFFFFF'; $rows .= "<tr style=\"background-color: {$bg};\">" . "<td style=\"border: 1px solid #CBD5E1; padding: 4px;\">{$i}</td>" . "<td style=\"border: 1px solid #CBD5E1; padding: 4px;\">Item {$i}</td>" . "<td style=\"border: 1px solid #CBD5E1; padding: 4px;\">In stock</td>" . '</tr>';}
$html = <<<HTML<table style="width: 100%; border-collapse: collapse;"> <thead> <tr style="background-color: #1E3A8A; color: #FFFFFF;"> <th style="border: 1px solid #1E3A8A; padding: 6px;">#</th> <th style="border: 1px solid #1E3A8A; padding: 6px;">Name</th> <th style="border: 1px solid #1E3A8A; padding: 6px;">Status</th> </tr> </thead> <tbody>{$rows}</tbody></table>HTML;
$doc = Document::createStandalone();$doc->setTitle('Inventory report');$doc->addPage();$doc->writeHtml($html);
$out = getenv('NEXTPDF_OUT');$doc->save($out !== false ? $out : __DIR__ . '/paginate-large-html-tables.pdf');
echo "Wrote the paginated table PDF\n";Margini delle pagine di continuazione
Sezione intitolata “Margini delle pagine di continuazione”Le pagine di continuazione usano i margini superiore e inferiore del documento. La prima riga dopo un’interruzione di pagina inizia sotto il margine superiore e l’ultima riga prima di un’interruzione si ferma sopra il margine inferiore. Questo impedisce che una tabella lunga venga ritagliata contro il bordo della pagina. La stessa regola si applica sia a un blocco multipagina sia a una tabella multipagina.
Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Gli avvisi di impaginazione restano silenziosi in caso di successo. Quando una tabella si distribuisce correttamente su più pagine, non emette alcun avviso. Il motore genera un avviso
TABLE_ROW_OVERFLOWsolo per un layout degradato: quando non esiste un sink per le interruzioni di pagina, oppure quando una riga deve essere ricollocata per aprire una pagina. Trattare l’avviso come un segnale per semplificare la tabella, non come un errore. - Inserire l’intestazione nel
<thead>. Si ripetono solo le righe del<thead>. Una riga di intestazione lasciata nel<tbody>compare una sola volta. - Le righe devono essere suddivisibili. Una singola riga più alta dell’altezza utile della pagina genera
UnsplittableContentException. Scomporre il contenuto di quella riga, oppure accorciarlo. rowspandegrada attraverso un’interruzione. Una cella conrowspanche attraversa il limite di una pagina si frammenta (ADR-007). Per i raggruppamenti che devono restare integri durante l’impaginazione, usare invece una riga di intestazione di categoria. Consultare Funzionalità CSS non supportate.
Prestazioni
Sezione intitolata “Prestazioni”Il rendering scala linearmente con il numero di righe. Il motore trasmette l’output pagina per pagina e non mantiene mai un albero del documento; quindi, per una tabella lunga, la memoria non cresce con il numero di pagine. Il budget di questa ricetta è wall_ms: 2000, peak_mb: 96.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”Convalidare il numero di righe e la lunghezza delle celle nei dati forniti dall’utente per mantenere limitata la dimensione dell’output. Il motore esegue il rendering del testo anziché interpretarlo e non esegue alcuno script.
Conformità
Sezione intitolata “Conformità”| Dichiarazione | Specifica | Clausola | reference_id |
|---|---|---|---|
| Un gruppo di intestazione di tabella si ripete nei contenitori di frammentazione in cui una tabella viene suddivisa. | W3C CSS Tables 3 | css_tables_3#x1.x7.x2 | 53622ccb1bce2a0cc53bd70919fa4633a9376e2050f63a31a3fde9cb6595ec78 |
Contesto commerciale
Sezione intitolata “Contesto commerciale”Non applicabile.
Vedere anche
Sezione intitolata “Vedere anche”- HTML: sottosistema di rendering da HTML+CSS a PDF — rendering in passaggio singolo e comportamento di impaginazione.
- Impaginare una tabella HTML — dimensionamento delle colonne,
colspane bordi. - Impaginare contenuti HTML lunghi — interruzioni di pagina per contenuto a blocchi misto.
- Matrice di supporto CSS — stato di supporto per tabelle e impaginazione.