Aller au contenu

Paginer un grand tableau HTML sur plusieurs pages

Passe un seul grand <table> à writeHtml(). Le moteur le pagine sur autant de pages PDF que nécessaire selon le nombre de lignes. Le <thead> se répète en haut de chaque page, si bien que chaque page se lit comme un tableau complet. Cette recette génère un rapport de 91 lignes qui s’étend sur plusieurs pages. Tu n’as pas à scinder le tableau toi-même ni à calculer les sauts de page.

Fenêtre de terminal
composer require nextpdf/core

Quand un tableau dépasse la hauteur d’une page, conserve-le comme un seul élément <table>. Le moteur mesure chaque ligne, remplit la hauteur de page utile, ouvre une nouvelle page et poursuit le même tableau. Il restitue de nouveau les lignes du <thead> en haut de chaque page de continuation. Les pages de continuation conservent les marges supérieure et inférieure du document : la première ligne d’une nouvelle page commence donc sous la marge supérieure, pas au bord de la page.

Place les cellules d’en-tête dans un <thead> et les lignes de données dans un <tbody>. Seul le <thead> se répète. Veille à ce que chaque ligne puisse être scindée. Une ligne unique plus haute que la hauteur de page utile ne peut pas être paginée et lève UnsplittableContentException.

SymboleEmplacementRôle
Document::writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutputRestitue le HTML et pagine les tableaux selon les besoins.
Document::createStandalone(): selfNextPDF\Core\DocumentCrée un document autonome.
Document::addPage(): staticNextPDF\Core\DocumentOuvre la première page et définit la taille et les marges de la page.
<?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');

Les 91 lignes s’étendent sur plusieurs pages, et l’en-tête #/Name/Status se répète sur chaque page.

Cet exemple autonome applique un style à l’en-tête, alterne les lignes et écrit le PDF dans le chemin fourni par le harnais.

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

Les pages de continuation utilisent les marges supérieure et inférieure du document. La première ligne après un saut de page commence sous la marge supérieure, et la dernière ligne avant un saut s’arrête au-dessus de la marge inférieure. Cela évite qu’un long tableau soit rogné contre le bord de la page. La même règle s’applique à un bloc multipage comme à un tableau multipage.

  • Les avertissements de pagination sont silencieux en cas de succès. Quand un tableau s’étend proprement sur plusieurs pages, il n’émet aucun avertissement. Le moteur ne lève un avertissement TABLE_ROW_OVERFLOW que lorsque la mise en page se dégrade : s’il n’existe aucun puits de saut de page, ou si une ligne doit être déplacée pour ouvrir une page. Traite cet avertissement comme un signal pour simplifier le tableau, pas comme un échec.
  • Place l’en-tête dans <thead>. Seules les lignes du <thead> se répètent. Une ligne d’en-tête laissée dans <tbody> n’apparaît qu’une seule fois.
  • Les lignes doivent être scindables. Une ligne unique plus haute que la hauteur de page utile lève UnsplittableContentException. Décompose le contenu de cette ligne ou raccourcis-la.
  • rowspan se dégrade à travers un saut. Une cellule rowspan qui franchit une limite de page se fragmente (ADR-007). Pour les regroupements qui doivent rester intacts lors de la pagination, utilise plutôt une ligne d’en-tête de catégorie. Consulte Fonctionnalités CSS non prises en charge.

Le rendu évolue linéairement avec le nombre de lignes. Le moteur diffuse la sortie page par page et ne conserve jamais d’arbre de document ; la mémoire utilisée par un long tableau ne croît donc pas avec le nombre de pages. Le budget de cette recette est wall_ms: 2000, peak_mb: 96.

Valide le nombre de lignes et la longueur des cellules dans les données fournies par l’utilisateur afin de garder une taille de sortie bornée. Le moteur restitue le texte au lieu de l’interpréter, et il n’exécute aucun script.

ÉnoncéSpécificationClausereference_id
Un groupe d’en-tête de tableau se répète dans les conteneurs de fragmentation où un tableau est scindé.W3C CSS Tables 3css_tables_3#x1.x7.x253622ccb1bce2a0cc53bd70919fa4633a9376e2050f63a31a3fde9cb6595ec78

Sans objet.