Ga naar inhoud

Een grote HTML-tabel over meerdere pagina's pagineren

Geef één grote <table> door aan writeHtml(). De engine pagineert die over zoveel PDF-pagina’s als nodig is voor de rijen. De <thead> wordt bovenaan elke pagina herhaald, zodat elke pagina als complete tabel werkt. Dit recipe rendert een rapport met 91 rijen dat over meerdere pagina’s doorloopt. Je hoeft de tabel niet zelf te splitsen of pagina-einden te berekenen.

Terminal window
composer require nextpdf/core

Als een tabel hoger is dan één pagina, houd je die in één enkel <table>-element. De engine meet elke rij, vult de bruikbare paginahoogte, opent een nieuwe pagina en laat dezelfde tabel daar verderlopen. De engine rendert de <thead>-rijen bovenaan elke vervolgpagina opnieuw. Vervolgpagina’s behouden de boven- en ondermarges van het document, zodat de eerste rij op een nieuwe pagina onder de bovenmarge begint en niet aan de paginarand.

Plaats kopcellen in een <thead> en datarijen in een <tbody>. Alleen de <thead> wordt herhaald. Zorg dat elke rij splitsbaar blijft. Eén enkele rij die hoger is dan de bruikbare paginahoogte kan niet worden gepagineerd en veroorzaakt UnsplittableContentException.

SymboolLocatieRol
Document::writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutputRender HTML en pagineer tabellen wanneer dat nodig is.
Document::createStandalone(): selfNextPDF\Core\DocumentMaak een op zichzelf staand document.
Document::addPage(): staticNextPDF\Core\DocumentOpen de eerste pagina en stel het paginaformaat en de marges in.
<?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');

De 91 rijen lopen over meerdere pagina’s en de #/Name/Status-kop wordt op elke pagina herhaald.

Dit op zichzelf staande voorbeeld maakt de kop op, geeft de rijen afwisselende achtergrondkleuren en schrijft de PDF naar het pad dat de harness aanlevert.

<?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";

Vervolgpagina’s gebruiken de boven- en ondermarges van het document. De eerste rij na een pagina-einde begint onder de bovenmarge en de laatste rij vóór een einde stopt boven de ondermarge. Zo voorkom je dat een lange tabel tegen de paginarand wordt afgekapt. Dezelfde regel geldt voor een blok dat over meerdere pagina’s loopt en voor een tabel die over meerdere pagina’s loopt.

  • Bij correcte paginering verschijnen er geen pagineringswaarschuwingen. Als een tabel netjes over pagina’s loopt, geeft de engine geen waarschuwing. De engine geeft alleen een TABLE_ROW_OVERFLOW-waarschuwing bij een gedegradeerde lay-out: wanneer er geen pagina-einde-sink is of wanneer een rij moet worden verplaatst om een pagina te openen. Behandel de waarschuwing als een signaal om de tabel te vereenvoudigen, niet als fout.
  • Plaats de kop in <thead>. Alleen <thead>-rijen herhalen zich. Een koprij die in <tbody> staat, verschijnt maar één keer.
  • Rijen moeten splitsbaar zijn. Eén enkele rij die hoger is dan de bruikbare paginahoogte veroorzaakt UnsplittableContentException. Breek de inhoud van die rij op, of verkort die.
  • rowspan degradeert over een pagina-einde heen. Een rowspan-cel die een paginagrens kruist, fragmenteert (ADR-007). Gebruik in plaats daarvan een categorie-koprij voor groeperingen die tijdens de paginering intact moeten blijven. Zie Niet-ondersteunde CSS-functies.

Renderen schaalt lineair met het aantal rijen. De engine streamt de uitvoer pagina voor pagina en houdt nooit een documentboom vast; daardoor groeit het geheugenverbruik voor een lange tabel niet mee met het aantal pagina’s. Het budget voor dit recipe is wall_ms: 2000, peak_mb: 96.

Valideer het aantal rijen en de cellengte van door gebruikers aangeleverde data om de uitvoergrootte begrensd te houden. De engine rendert tekst in plaats van die te interpreteren en voert geen script uit.

VerklaringSpecClausereference_id
Een tabelkopgroep herhaalt zich over de fragmentatiecontainers waarin een tabel wordt gesplitst.W3C CSS Tables 3css_tables_3#x1.x7.x253622ccb1bce2a0cc53bd70919fa4633a9376e2050f63a31a3fde9cb6595ec78

Niet van toepassing.