从 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');