跳转到内容

HTML 表格排版

本示例会绘制一个包含表头、对齐单元格、边框和表尾行的 HTML 表格。在 CSS 支持矩阵中,表格属于「已验证」模块。本示例遵循 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 被评定为 已验证。这一评定由四项来源支撑:src/Html/Table/、Table 单元测试套件、TableParser 测试,以及合成黄金 PDF。

表格通过 writeHtml(string $html): static 绘制(NextPDF\Core\Concerns\HasTextOutput)。该引擎支持标准表格 markup(标记语言)。支持的标签包括 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 分页器会将该单元格拆分开来(ADR-007)。无法拆分的超高单元格可能会引发 UnsplittableContentException
  • 空白单元格。 空的 <td> 仍会占用它在网格中的位置。它不会被折叠掉。

表格缓冲区生命周期很短,并且只限于其容器范围内。解析成本与单元格数量呈线性关系,另有一趟复杂度为 O(rows x cols) 的列宽计算。预算为 wall_ms: 1500, peak_mb: 96。请将单个表格控制在 ADR-020 的节点上限之内,也就是每个场景最多 5,000 个节点。

CSS 支持矩阵摘录(仅列出「已验证」的条目)

标题为“CSS 支持矩阵摘录(仅列出「已验证」的条目)”的章节

此摘录只重现 已验证 条目,这些条目取自经过真实性审核的 CSS 支持矩阵

W3C 模块层级状态证据
CSS Table 表格(css_tables_33已验证src/Html/Table/tests/Unit/Html/Table/,以及 TableParser 测试与黄金 PDF
CSS Flexible Box Layout 弹性盒布局(css_flexbox_11已验证src/Html/Flex/tests/Unit/Html/Flex/
CSS Grid Layout 网格布局(css_grid_11已验证src/Html/Grid/,WPT 语料库
CSS Cascading and Inheritance 层叠与继承(css_cascade_33已验证src/Html/Cascade/

background-color 在此用于行的条纹背景,在矩阵中被评定为「已宣称」。依据 Phase 0 审核,其适用范围是表格单元格。它对表格行会正常绘制,但并未列为「已验证」。

表格缓冲区是流式模型中载明的例外。它生命周期很短且有界,并不是通用 DOM。不要依赖表格为表格外部的内容提供树状上下文。

FormattingContextFactory::startTable() 通过布局层的契约读取 CSS。它不会在分派过程中解析原始的 $css[...]。对外公开的接口保持为 writeHtml()

在 50 MB 的活动内存上限内,一个表格格式化上下文受限于最多 5,000 个节点和 20 层嵌套深度(ADR-020)。对于非常大的表格,请将其切分或分页处理。不要把它绘制成单个过大的上下文。

来自不可信输入的表格标记语言,会受到与其他 HTML 相同的元素数量和嵌套深度上限约束。请验证用户组装的表格数据。renderer(渲染器)不会执行内容,且在默认策略下也不会获取任意远程资源。

陈述规范条款参考 ID
列的使用宽度由表格列宽计算算法在使用表格宽度下确定。W3C CSS Table Level 3 标准css_tables_3#x1.x4.x9.x3(条款编号)
在固定模式下,计算列宽时会忽略单元格内容。W3C CSS Table Level 3 标准css_tables_3#x1.x4.x5.x1.p6(条款编号)

本示例展示 NextPDF 如何绘制受支持的 HTML 表格。CSS Table Level 3 在支持矩阵中为「已验证」,此处用到的其他 CSS 模块则按该矩阵的等级评定。

不适用。