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 授權釋出。