Skip to content

HTML 解析器

Html 模块(共 8 个类)提供内置的 HTML 转 PDF 渲染器。它能解析 HTML/CSS 的子集语法,直接将内容渲染到 PDF 中,不需要外部浏览器。

核心类

职责
HtmlParser主要入口点 — 将 HTML 进行分词并渲染
CssRule解析 CSS 选择器与声明,计算特异性(specificity)
HtmlStyleState追踪嵌套的样式状态(字体、颜色、对齐)
TableParser处理 <table> 排版 — 列宽、合并单元格、表头重复
HtmlTagHandler分派开启/关闭标签的回调函数
HtmlTokenizer将原始 HTML 拆分为标签与文字 token
HtmlEntity解码具名与数值 HTML 实体
InlineStyle解析 style="..." 属性字符串

writeHtml()

writeHtml() 是最常用的 HTML 渲染方法,将 HTML 字符串直接输出到当前的页面位置:

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->addPage()
    ->setFont('DejaVuSans', '', 10)
    ->writeHtml('<h1>Hello World</h1><p>This is a paragraph.</p>');

方法签名

php
writeHtml(
    string $html,
    bool   $ln    = true,
    bool   $fill  = false,
    bool   $reseth = false,
    bool   $cell  = false,
    string $align = ''
): static
参数说明
$html要渲染的 HTML 字符串
$ln渲染完成后是否换行
$fill是否填满单元格背景
$reseth是否重置起始高度
$cell是否以单元格模式渲染
$align水平对齐方式

writeHtmlCell()

在指定的矩形区域内渲染 HTML 内容,适合用于精确的布局排版:

php
writeHtmlCell(
    float  $w,
    float  $h,
    float  $x,
    float  $y,
    string $html,
    mixed  $border      = 0,
    int    $ln          = 0,
    bool   $fill        = false,
    bool   $reseth      = true,
    string $align       = '',
    bool   $autopadding = true
): static
php
$pdf->writeHtmlCell(90, 0, 10, 50, '<p>左栏内容</p>')
    ->writeHtmlCell(90, 0, 105, 50, '<p>右栏内容</p>');

支持的 HTML 标签

区块元素: <h1> ~ <h6><p><div><blockquote><pre><hr>

行内元素: <b><strong><i><em><u><s><del><sup><sub><span><code><a><br>

列表: <ul><ol><li> — 支持最多 4 层嵌套。

表格: <table><tr><th><td> — 详见下方「表格引擎」。

媒体: <img src="..." width="..." height="...">

CSS 支持

样式可以通过 <style> 区块、行内 style 属性,或两者同时使用。解析器会依照特异性(specificity)与层叠顺序(cascade order)应用样式。

属性示例值
font-familyDejaVuSans, Helvetica, serif
font-size12pt16px1.2em
font-weight / font-stylebolditalicnormal
color / background-color#ff6600rgb(255,102,0)red
text-alignleftcenterrightjustify
text-decorationunderlineline-throughnone
line-height1.518pt
margin / padding5px10px 20px
border1px solid #ddd
width / height100%200px

CSS 规则解析(CssRule)

CssRule 类负责计算特异性(specificity),用以决定层叠顺序:

  • 元素选择器 h1td — 特异性 (0, 0, 1)
  • 类选择器 .highlight — 特异性 (0, 1, 0)
  • ID 选择器 #header — 特异性 (1, 0, 0)
  • 复合选择器 table td.active — 各部分的特异性相加

当特异性相同时,以来源顺序决定(后面的声明覆盖前面的)。

样式状态(HtmlStyleState)

HtmlStyleState 使用栈(stack)维护样式上下文。每当遇到开启标签就推入(push)一层状态;遇到关闭标签就弹出(pop)。这确保嵌套样式能正确解析,不会泄漏到相邻的兄弟元素。

表格引擎(TableParser)

表格引擎是 Html 模块中最复杂的部分,支持以下功能:

  • colspan / rowspan — 水平与垂直合并单元格
  • 自动列宽 — 根据内容比例分配列宽
  • 固定列宽 — 通过 <td><th> 上的 CSS width 设置
  • 表头样式<th> 默认应用粗体文字
  • 自动分页 — 表格超过页面高度时会自动分页,并在新页面重复表头

完整示例:含样式的 HTML 发票

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->addPage()
    ->setFont('DejaVuSans', '', 10)
    ->writeHtml('
        <style>
            h1 { color: #ff6600; font-size: 18pt; }
            .highlight { background-color: #ffffcc; padding: 5px; }
            table { border-collapse: collapse; width: 100%; }
            th { background-color: #333; color: #fff; padding: 8px; }
            td { border: 1px solid #ddd; padding: 8px; }
            .text-right { text-align: right; }
            .total-row { background-color: #f0f0f0; font-weight: bold; }
        </style>

        <h1>发票 #2026-001</h1>
        <p class="highlight">到期日:2026-03-01</p>

        <table>
            <tr>
                <th>品名</th>
                <th>数量</th>
                <th>单价</th>
                <th>金额</th>
            </tr>
            <tr>
                <td>Widget A</td>
                <td class="text-right">10</td>
                <td class="text-right">NT$ 500</td>
                <td class="text-right">NT$ 5,000</td>
            </tr>
            <tr>
                <td>Widget B</td>
                <td class="text-right">3</td>
                <td class="text-right">NT$ 1,200</td>
                <td class="text-right">NT$ 3,600</td>
            </tr>
            <tr class="total-row">
                <td colspan="3" class="text-right">合计</td>
                <td class="text-right">NT$ 8,600</td>
            </tr>
        </table>
    ');

提示

  • 调用 writeHtml() 之前,请务必先调用 setFont() — 解析器会将当前的字体作为未设置样式文字的默认字体。
  • 如果需要完整的 CSS3 支持(Flexbox、Grid、Web Fonts),请改用 Artisan 包。
  • 大型 HTML 表格在启用自动分页的情况下,会自动跨页渲染。
  • 建议将复杂的 CSS 放在 <style> 区块中,而非使用行内样式,以利维护和调试。

以 LGPL-3.0-or-later 许可证发布。