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
): staticphp
$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-family | DejaVuSans, Helvetica, serif |
font-size | 12pt、16px、1.2em |
font-weight / font-style | bold、italic、normal |
color / background-color | #ff6600、rgb(255,102,0)、red |
text-align | left、center、right、justify |
text-decoration | underline、line-through、none |
line-height | 1.5、18pt |
margin / padding | 5px、10px 20px |
border | 1px solid #ddd |
width / height | 100%、200px |
CSS 規則解析(CssRule)
CssRule 類別負責計算特異性(specificity),用以決定層疊順序:
- 元素選擇器
h1、td— 特異性 (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>上的 CSSwidth設定 - 表頭樣式 —
<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>區塊中,而非使用行內樣式,以利維護和除錯。