从 mPDF 迁移
本指南协助您从 mPDF(mpdf/mpdf)迁移至 TCPDF-Next。mPDF 是一套类似 DomPDF 的 HTML 转 PDF 库,但具备更广泛的 CSS 支持与额外功能。TCPDF-Next 提供 mPDF 功能的超集,并符合现代标准。
功能比较
| 特性 | mPDF | TCPDF-Next |
|---|---|---|
| PHP 版本 | 7.4+ | 8.5+ |
| PDF 版本 | PDF 1.4 / 1.7 | PDF 2.0 |
| 架构 | HTML/CSS 为核心 | PDF 原生,支持 HTML |
| CJK 支持 | 有(大型字体文件) | 有(优化子集) |
| RTL / BiDi | 有 | 有(UAX #9 合规) |
| 加密 | RC4-40、RC4-128、AES-128、AES-256 | 仅 AES-256(PDF 2.0) |
| 数字签名 | 不支持 | PAdES B-B 至 B-LTA |
| PDF/A | PDF/A-1b、PDF/A-3b(部分) | PDF/A-4(完整) |
| 无障碍 | 有限 | 标记式 PDF(PDF/UA) |
| 内存使用 | 高(完整 DOM + 图片存于内存) | 中等(流式输出) |
| 依赖包 | 10+ 个 Composer 包 | 零运行时依赖 |
何时该迁移
若您需要以下功能,请考虑从 mPDF 迁移至 TCPDF-Next:
- 数字签名 — mPDF 不支持签名功能
- 现代 PDF/A 合规 — PDF/A-4(不仅是 PDF/A-1b)
- 更佳安全性 — 仅 AES-256,无 RC4
- 更低内存使用 — 大型文件的流式输出
- 更少依赖包 — 零运行时依赖 vs. 10+
- 无障碍 — 具结构元素的标记式 PDF
逐步迁移
步骤 1:更新依赖包
bash
composer remove mpdf/mpdf
composer require yeee-fang/tcpdf-nextTIP
移除 mPDF 同时也会移除其 10 多个传递依赖包(psr/log、psr/http-message、setasign/fpdi 等),大幅简化您的依赖树。
步骤 2:替换文档创建
mPDF(迁移前):
php
$mpdf = new \Mpdf\Mpdf([
'mode' => 'utf-8',
'format' => 'A4',
'margin_left' => 15,
'margin_right' => 15,
'margin_top' => 16,
'margin_bottom' => 16,
'default_font_size' => 12,
'default_font' => 'dejavusans',
]);
$mpdf->SetTitle('My Document');
$mpdf->SetAuthor('Jane Doe');TCPDF-Next(迁移后):
php
use YeeeFang\TcpdfNext\Document\PdfDocument;
use YeeeFang\TcpdfNext\Document\PageFormat;
use YeeeFang\TcpdfNext\Document\Margins;
use YeeeFang\TcpdfNext\Html\HtmlRenderer;
$pdf = PdfDocument::create()
->setPageFormat(PageFormat::A4)
->setMargins(new Margins(left: 15, right: 15, top: 16, bottom: 16))
->setTitle('My Document')
->setAuthor('Jane Doe')
->build();
$renderer = new HtmlRenderer($pdf);
$renderer->setDefaultFont('DejaVuSans', size: 12);步骤 3:替换 HTML 写入
mPDF(迁移前):
php
$mpdf->WriteHTML($stylesheet, \Mpdf\HTMLParserMode::HEADER_CSS);
$mpdf->WriteHTML($htmlBody, \Mpdf\HTMLParserMode::HTML_BODY);TCPDF-Next(迁移后):
php
$renderer = new HtmlRenderer($pdf);
$renderer->addStylesheet($stylesheet);
$renderer->writeHtml($htmlBody);步骤 4:替换页眉页脚
mPDF(迁移前):
php
$mpdf->SetHTMLHeader('<div style="text-align: center;">公司名称</div>');
$mpdf->SetHTMLFooter('<div style="text-align: center;">第 {PAGENO} 页,共 {nbpg} 页</div>');TCPDF-Next(迁移后):
php
$pdf->setHtmlHeader('<div style="text-align: center;">公司名称</div>');
$pdf->setHtmlFooter('<div style="text-align: center;">第 {{pageNumber}} 页,共 {{totalPages}} 页</div>');
// 或使用回调方式(更灵活)
$pdf->onPageFooter(function (Page $page, int $pageNumber, int $totalPages) {
$page->addText("第 {$pageNumber} 页,共 {$totalPages} 页")
->setPosition(105, 287)
->setFont('Helvetica', size: 9)
->setAlignment(Alignment::CENTER);
});步骤 5:替换水印
mPDF(迁移前):
php
$mpdf->SetWatermarkText('DRAFT', 0.1);
$mpdf->showWatermarkText = true;TCPDF-Next(迁移后):
php
use YeeeFang\TcpdfNext\Document\Watermark;
$pdf->setWatermark(
Watermark::text('DRAFT')
->setOpacity(0.1)
->setRotation(45)
->setFont('Helvetica', size: 72)
->setColor(Color::rgb(200, 200, 200))
);步骤 6:替换 CJK 与 RTL 文字
mPDF(迁移前):
php
$mpdf = new \Mpdf\Mpdf(['mode' => '+aCJK', 'autoScriptToLang' => true, 'autoLangToFont' => true]);
$mpdf->SetDirectionality('rtl');TCPDF-Next(迁移后):
php
// CJK 支持(注册 CJK 字体)
$pdf->getFontManager()->registerFont('/path/to/NotoSansCJK-Regular.ttc', 'NotoSansCJK');
$renderer->setAutoFontDetection(true); // 依脚本自动选取字体
// RTL(通过 Unicode BiDi 算法自动处理)
$renderer->writeHtml('<div dir="rtl">مرحبا بالعالم</div>');步骤 7:替换输出
mPDF(迁移前):
php
$mpdf->Output('/path/to/file.pdf', \Mpdf\Output\Destination::FILE);
$mpdf->Output('doc.pdf', \Mpdf\Output\Destination::DOWNLOAD);
$content = $mpdf->Output('', \Mpdf\Output\Destination::STRING_RETURN);TCPDF-Next(迁移后):
php
$pdf->save('/path/to/file.pdf'); // 保存至文件
$bytes = $pdf->toString(); // 以字符串返回
// 下载(Web 框架)
return response($pdf->toString(), 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="doc.pdf"',
]);mPDF 自定义标签映射
mPDF 支持非标准 HTML 的自定义标签,需要进行适配:
| mPDF 自定义标签 | TCPDF-Next 对应 |
|---|---|
<tocpagebreak> | $pdf->addTableOfContentsPage() |
<tocentry> | $toc->addEntry(...) |
<barcode> | $page->addBarcode(...) |
<columnbreak> | $renderer->columnBreak() |
<pagebreak> | 标准 <div style="page-break-before: always"> |
<bookmark> | $pdf->addBookmark(...) |
<watermarktext> | $pdf->setWatermark(Watermark::text(...)) |
<watermarkimage> | $pdf->setWatermark(Watermark::image(...)) |
依赖包精简
从 mPDF 迁移至 TCPDF-Next 可大幅精简依赖树:
移除的 mPDF 依赖包:
mpdf/mpdf+ 10 多个传递包psr/log、psr/http-message、setasign/fpdi、mpdf/qrcode等
新增的 TCPDF-Next 依赖包:
yeee-fang/tcpdf-next(零运行时依赖)