從 DomPDF 遷移
本指南協助您從 DomPDF(dompdf/dompdf)遷移至 TCPDF-Next。這兩套函式庫的架構根本不同 — DomPDF 以 HTML/CSS 為核心,而 TCPDF-Next 以 PDF 為核心並支援 HTML 渲染 — 但對於大多數使用情境,遷移過程相當直接。
架構比較
| 面向 | DomPDF | TCPDF-Next |
|---|---|---|
| 設計哲學 | HTML/CSS 轉 PDF 渲染器 | PDF 原生,支援 HTML 渲染 |
| 輸入格式 | HTML + CSS | PHP API、HTML 或混合使用 |
| PDF 版本 | PDF 1.3 / 1.7 | PDF 2.0 |
| PHP 版本 | 7.1+ | 8.5+ |
| 字型支援 | TTF(透過 php-font-lib) | TTF/OTF 原生解析與子集化 |
| 加密 | 不支援 | AES-256(PDF 2.0) |
| 數位簽章 | 不支援 | PAdES B-B 至 B-LTA |
| PDF/A | 不支援 | PDF/A-4(完整) |
| 無障礙 | 不支援 | 標記式 PDF(PDF/UA) |
| 條碼 | 不支援 | QR、Data Matrix、Code 128 等 |
| 記憶體使用 | 高(DOM 存於記憶體) | 中等(串流輸出) |
何時該遷移
若您需要以下功能,請考慮從 DomPDF 遷移至 TCPDF-Next:
- 數位簽章 — DomPDF 不支援簽章功能
- PDF/A 合規 — 歸檔、電子發票(ZUGFeRD)或政府需求
- 加密 — 保護機敏文件
- 更佳效能 — 大型文件的記憶體使用更低
- 條碼 — 無需外部函式庫的原生條碼產生
- 無障礙 — 螢幕閱讀器可用的標記式 PDF
逐步遷移
步驟 1:更新相依套件
bash
composer remove dompdf/dompdf
composer require yeee-fang/tcpdf-next步驟 2:替換基礎 HTML 轉 PDF
DomPDF(遷移前):
php
use Dompdf\Dompdf;
use Dompdf\Options;
$options = new Options();
$options->set('defaultFont', 'Helvetica');
$options->set('isRemoteEnabled', true);
$dompdf = new Dompdf($options);
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
file_put_contents('/path/to/output.pdf', $dompdf->output());TCPDF-Next(遷移後):
php
use YeeeFang\TcpdfNext\Document\PdfDocument;
use YeeeFang\TcpdfNext\Document\PageFormat;
use YeeeFang\TcpdfNext\Html\HtmlRenderer;
$pdf = PdfDocument::create()
->setPageFormat(PageFormat::A4)
->build();
$renderer = new HtmlRenderer($pdf);
$renderer->setDefaultFont('Helvetica', size: 12);
$renderer->writeHtml($html);
$pdf->save('/path/to/output.pdf');步驟 3:替換 CSS 樣式
DomPDF 透過 CSS 渲染 HTML,TCPDF-Next 的 HTML 渲染器同樣支援 CSS。大部分 CSS 無需修改即可運作:
php
// 相同的 HTML/CSS 在 TCPDF-Next 的 HTML 渲染器中可直接使用
$renderer = new HtmlRenderer($pdf);
$renderer->writeHtml($html); // 與 DomPDF 使用相同的 HTMLTIP
TCPDF-Next 的 HTML 渲染器支援大部分 CSS 2.1 屬性與部分 CSS 3 屬性(不支援 flexbox,複雜版面請使用表格)。若遇到 CSS 渲染差異,請查閱 HTML 渲染器文件 瞭解支援的屬性。
步驟 4:替換圖片處理
DomPDF(遷移前):
php
$options = new Options();
$options->set('isRemoteEnabled', true);
$options->set('chroot', '/var/www/html/');TCPDF-Next(遷移後):
php
use YeeeFang\TcpdfNext\Security\ResourcePolicy;
// 設定資源存取政策(比 DomPDF 的 chroot 更安全)
$policy = ResourcePolicy::create()
->allowLocalDirectory('/var/www/html/images/')
->allowDomain('cdn.example.com');
$pdf = PdfDocument::create()
->setResourcePolicy($policy)
->build();步驟 5:替換頁首頁尾
DomPDF(遷移前):
php
$dompdf->render();
$canvas = $dompdf->getCanvas();
$canvas->page_text(36, 18, "Header text", "Helvetica", 10, [0, 0, 0]);
$canvas->page_text(36, 780, "Page {PAGE_NUM} of {PAGE_COUNT}", "Helvetica", 8, [0, 0, 0]);TCPDF-Next(遷移後):
php
$pdf->onPageHeader(function (Page $page, int $pageNumber) {
$page->addText('Header text')
->setPosition(15, 10)
->setFont('Helvetica', size: 10);
});
$pdf->onPageFooter(function (Page $page, int $pageNumber, int $totalPages) {
$page->addText("Page {$pageNumber} of {$totalPages}")
->setPosition(15, 280)
->setFont('Helvetica', size: 8);
});功能對應表
| DomPDF 功能 | TCPDF-Next 對應 |
|---|---|
$dompdf->loadHtml($html) | $renderer->writeHtml($html) |
$dompdf->loadHtmlFile($url) | $renderer->writeHtmlFile($path) |
$dompdf->setPaper('A4') | $pdf->setPageFormat(PageFormat::A4) |
$dompdf->render() | 自動(儲存/toString 時觸發) |
$dompdf->output() | $pdf->toString() |
$dompdf->stream() | 使用框架的回應輔助方法 |
isRemoteEnabled 選項 | ResourcePolicy::allowDomain() |
chroot 選項 | ResourcePolicy::allowLocalDirectory() |
defaultFont 選項 | $renderer->setDefaultFont() |
CSS page-break-before | HTML 渲染器支援 |
| 內嵌 PHP | 不支援(安全風險) |
遷移後新增的能力
從 DomPDF 遷移後,您可使用 DomPDF 不支援的功能:
php
// 數位簽章
$signer = new PdfSigner($pdf);
$signer->setCertificate($cert, $privateKey)
->setLevel(SignatureLevel::PAdES_B_LTA)
->sign();
// PDF/A-4 歸檔
$pdf = PdfDocument::create()
->setPdfALevel(PdfALevel::PDF_A_4)
->build();
// AES-256 加密
$pdf->setEncryption()
->setAlgorithm(EncryptionAlgorithm::AES256)
->setUserPassword('password')
->apply();
// 條碼與 QR Code
$qr = BarcodeFactory::qrCode('https://example.com');
$page->addBarcode($qr)->setPosition(15, 200)->setSize(30, 30);Laravel 專屬遷移
若您使用 DomPDF 搭配 Laravel(透過 barryvdh/laravel-dompdf):
遷移前(laravel-dompdf):
php
use Barryvdh\DomPDF\Facade\Pdf;
$pdf = Pdf::loadView('invoice', $data);
return $pdf->download('invoice.pdf');遷移後(TCPDF-Next 搭配 Laravel):
php
use YeeeFang\TcpdfNext\Laravel\Facades\Pdf;
$pdf = Pdf::loadView('invoice', $data)
->setPdfALevel(PdfALevel::PDF_A_4)
->sign($cert, $privateKey, SignatureLevel::PAdES_B_LTA)
->download('invoice.pdf');