コンテンツにスキップ

HTML テーブルをレイアウトする

このレシピでは、ヘッダー、配置を揃えたセル、罫線、フッター行を備えた HTML テーブルをレンダリングします。テーブルは CSS サポートマトリックスで Verified(検証済み)のモジュールです。このレシピは examples/09-html-table.php に沿っています。

Terminal window
composer require nextpdf/core:^3

このバージョン制約は nextpdf/core パッケージに対するものです。このサンプルは PHP 8.4 で動作します。

HTML エンジンには、テーブル専用のパイプライン(src/Html/Table/)があります。TableParser は行とセルを短命なバッファーに収集し、その後にテーブルがレイアウトされ、描画されます。これは、ADR-001 の DOM を保持しないモデルで唯一認められている逸脱です。このバッファーは短命で、そのコンテナー内にスコープが限定されます。永続的な DOM ではありません。

列の幅は CSS Table モデルに従います。テーブルは指定された使用幅でレイアウトされ、その後、列サイズ決定アルゴリズムが各列の使用幅を設定します(W3C CSS Table Level 3)。table-layout: fixed では、幅の計算時にセルの内容は無視されます。代わりに、最初の行と明示的に指定された列の幅がレイアウトを決定します(W3C CSS Table Level 3)。

CSS Table Level 3 は、マトリックスで Verified と評価されています。この評価は、4 つの根拠に裏付けられています。src/Html/Table/、Table ユニットスイート、TableParser テスト、合成されたゴールデン PDF です。

テーブルは writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutput)を通じてレンダリングされます。エンジンは標準的なテーブルマークアップをサポートします。サポートされるタグは、tabletheadtbodytfoottrth、および td です。サポートされる属性は、bordercellpaddingcellspacingcolspan、およびセルごとの style です。完全な PHPDoc テーブルはソースから生成されます。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
$doc->writeHtml(
'<table border="1" cellpadding="5"><tr><th>SKU</th><th>Qty</th></tr>'
. '<tr><td>NPD-CORE</td><td style="text-align: right;">1</td></tr></table>'
);
$doc->save(__DIR__ . '/out.pdf');

このサンプルは自己完結型で、ハーネスで実行できます。examples/09-html-table.php を反映しており、スタイル付きのヘッダー、交互に色を付けた行の背景、配置を揃えた数値列、フッターの合計を示しています。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('HTML Table');
$doc->addPage();
$html = <<<'HTML'
<h1 style="color: #1E3A8A;">Product Inventory Report</h1>
<table border="1" cellpadding="5" cellspacing="0" style="width: 100%;">
<thead>
<tr style="background-color: #1E3A8A; color: #FFFFFF;">
<th style="width: 10%;">#</th>
<th style="width: 45%;">Product</th>
<th style="width: 20%; text-align: center;">SKU</th>
<th style="width: 25%; text-align: right;">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>NextPDF Core License</td>
<td style="text-align: center;">NPD-CORE</td>
<td style="text-align: right;">$0.00</td>
</tr>
<tr style="background-color: #F8FAFC;">
<td>2</td>
<td>NextPDF Pro License</td>
<td style="text-align: center;">NPD-PRO</td>
<td style="text-align: right;">$299.00</td>
</tr>
</tbody>
<tfoot>
<tr style="background-color: #1E293B; color: #FFFFFF; font-weight: bold;">
<td colspan="3" style="text-align: right;">Grand total:</td>
<td style="text-align: right;">$299.00</td>
</tr>
</tfoot>
</table>
HTML;
$doc->writeHtml($html);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
$doc->save($out !== false ? $out : __DIR__ . '/html-table-layout.pdf');
echo "Wrote html-table-layout.pdf\n";

想定される STDOUT:

Wrote html-table-layout.pdf
  • パーセント指定の幅。 列の width に指定したパーセント値は、テーブルの使用幅を基準に resolve(解決)されます。列サイズ決定アルゴリズムは、合計が 100 にならないパーセント値を正規化します。正確なピクセル幅を前提にしないでください。
  • colspan 結合されたセルは、それがまたがる列全体にわたる幅の分配に関与します。ほとんどの列にまたがるフッターの合計は、一般的でサポートされているパターンです。
  • 罫線モデル。 一部のテーブルフィクスチャでは、border-collapse のデフォルトが CSS の初期値と異なります。罫線のレンダリングが重要な場合は、明示的に設定してください。
  • 改ページをまたぐ rowspan。 rowspan を持つセルはページ境界をまたぐことがあり、その場合は rowspan ページネーターがそのセルを分割します(ADR-007)。分割できない非常に背の高いセルは、UnsplittableContentException を発生させることがあります。
  • 空のセル。 空の <td> も、引き続きグリッドのスロットを占有します。詰めて消されることはありません。

テーブルバッファーは短命で、そのコンテナー内にスコープが限定されます。解析コストはセル数に対して線形であり、そこに O(rows x cols) の列サイズ決定パスが加わります。バジェットは wall_ms: 1500, peak_mb: 96 です。単一のテーブルは、コンテキストごとに 5,000 ノードという ADR-020 のノード上限内に収めてください。

この抜粋では、Verified の行のみを、真正性の監査が済んでいる CSS サポートマトリックスから再掲します。

W3C モジュールレベルステータス根拠
CSS Table(css_tables_33Verifiedsrc/Html/Table/tests/Unit/Html/Table/ + TableParser テスト + ゴールデン PDF
CSS Flexible Box Layout(フレキシブルボックスレイアウト、css_flexbox_11Verifiedsrc/Html/Flex/tests/Unit/Html/Flex/
CSS Grid Layout(css_grid_11Verifiedsrc/Html/Grid/、WPT コーパス
CSS Cascading and Inheritance(css_cascade_33Verifiedsrc/Html/Cascade/

background-color は、ここで行のしま模様に使用されており、マトリックスでは「Claimed」と評価されています。Phase 0 の監査によれば、適用範囲はテーブルのセルです。これはテーブルの行に対してレンダリングされますが、Verified としては掲載されていません。

テーブルバッファーは、ストリーミングモデルで文書化されている例外です。これは短命で上限が定められており、汎用的な DOM ではありません。テーブルの外側のコンテンツにツリーのコンテキストを提供する目的で、テーブルに依存しないでください。

FormattingContextFactory::startTable() は、レイアウトレイヤーの契約を通じて CSS を読み取ります。ディスパッチ中に、生の $css[...] を解析することはありません。パブリックなサーフェスは writeHtml() のままです。

テーブルのフォーマットコンテキストは、50 MB のアクティブメモリー上限の範囲内で、5,000 ノードかつ深さ 20 レベルに制限されます(ADR-020)。非常に大きなテーブルは、分割するかページに分けてください。単一の過大なコンテキストとしてレンダリングしないでください。

信頼できない入力に由来するテーブルマークアップは、他の HTML と同じ要素数およびネストの上限で制限されます。ユーザーが組み立てたテーブルデータは検証してください。レンダラーはコンテンツを実行せず、デフォルトのポリシーでは任意のリモートリソースを取得しません。

記述仕様条項リファレンス ID
テーブルの使用幅において、テーブルの列サイズ決定アルゴリズムによって決定される列の使用幅W3C CSS Table Level 3css_tables_3#x1.x4.x9.x3
固定モードで、列の幅の計算時に無視されるセルの内容W3C CSS Table Level 3css_tables_3#x1.x4.x5.x1.p6

このレシピは、NextPDF がサポート対象の HTML テーブルをどのようにレンダリングするかを示します。CSS Table Level 3 はサポートマトリックスで Verified であり、ここで使用されている他の CSS モジュールもそのマトリックスに従って評価されています。

該当しません。