Skip to content

从 mPDF 迁移

本指南协助您从 mPDF(mpdf/mpdf)迁移至 TCPDF-Next。mPDF 是一套类似 DomPDF 的 HTML 转 PDF 库,但具备更广泛的 CSS 支持与额外功能。TCPDF-Next 提供 mPDF 功能的超集,并符合现代标准。

功能比较

特性mPDFTCPDF-Next
PHP 版本7.4+8.5+
PDF 版本PDF 1.4 / 1.7PDF 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/APDF/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-next

TIP

移除 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/logpsr/http-messagesetasign/fpdimpdf/qrcode

新增的 TCPDF-Next 依赖包:

  • yeee-fang/tcpdf-next(零运行时依赖)

延伸阅读

以 LGPL-3.0-or-later 许可证发布。