跳到內容

讓大型 HTML 表格跨頁分頁

將大型 <table> 傳給 writeHtml()。引擎會依列數需求,將它分頁成所需數量的 PDF 頁面。<thead> 會在每一頁頂端重複,因此每一頁都會呈現為完整表格。本範例會繪製一份橫跨數頁的 91 列報表。你不需要自行切分表格,也不需要自行計算斷頁。

Terminal window
composer require nextpdf/core

當表格高度超過一頁時,請將它保留為單一 <table> 元素。引擎會量測每一列,填滿可用的頁面高度後另起新頁,並接續繪製同一個表格。引擎會在每個續頁頂端再次繪製 <thead> 列。續頁會保留文件的上下邊界,因此新頁上的第一列會從上邊界下方開始,而不是貼著頁緣開始。

請將標題儲存格放在 <thead>,將資料列放在 <tbody>。只有 <thead> 會重複。請確保每一列都可切分。若單一列高於可用的頁面高度,就無法分頁,並會引發 UnsplittableContentException

符號位置角色
Document::writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutput繪製 HTML,並視需要為表格分頁。
Document::createStandalone(): selfNextPDF\Core\Document建立獨立文件。
Document::addPage(): staticNextPDF\Core\Document開啟第一頁並設定頁面大小與邊界。
<?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');

這 91 列會跨越數頁排版,而 #/Name/Status 標題會在每一頁重複。

這個自足範例會為標題加上樣式、為資料列加上條紋,並將 PDF 寫入測試載具提供的路徑。

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

續頁會沿用文件的上下邊界。斷頁後的第一列會從上邊界下方開始,而斷頁前的最後一列會停在下邊界上方。這可避免長表格貼著頁緣而被裁切。同一規則也適用於多頁區塊與多頁表格。

  • 成功分頁時不會出現警告。 當表格乾淨地跨越多頁排版時,不會發出任何警告。引擎只會在版面配置降級時引發 TABLE_ROW_OVERFLOW 警告:當沒有斷頁接收端時,或當某一列必須被重新安置為某頁的開頭時。請將這個警告視為簡化表格的訊號,而不是失敗。
  • 將標題放進 <thead> 只有 <thead> 列會重複。留在 <tbody> 的標題列只會出現一次。
  • 列必須可切分。 若單一列高於可用的頁面高度,會引發 UnsplittableContentException。請將該列的內容拆開,或縮短它。
  • rowspan 跨越斷頁時會降級。 跨越頁面邊界的 rowspan 儲存格會被切分(ADR-007)。若成組內容在分頁期間必須維持完整,請改用類別標題列。請參見 不支援的 CSS 功能

繪製成本會隨列數線性增加。引擎會逐頁串流輸出,且不會保留文件樹,因此長表格的記憶體用量不會隨頁數成長。本範例的預算為 wall_ms: 2000, peak_mb: 96

請驗證使用者提供資料的列數與儲存格長度,讓輸出大小維持在有限範圍內。引擎只會繪製文字,不會解讀文字,也不會執行任何指令稿。

陳述規範條款reference_id
表格標題群組會在表格被切分而成的各分段容器(fragmentation containers)中重複。W3C CSS Tables 3css_tables_3#x1.x7.x253622ccb1bce2a0cc53bd70919fa4633a9376e2050f63a31a3fde9cb6595ec78

不適用。