
本文介绍如何在 php 中利用 fpdi 库,以用户上传的 pdf 文件为模板,动态填充或叠加内容并生成新的 pdf 文档,适用于合同、发票、证书等场景。
在 PHP 开发中,若需基于用户上传的 PDF 模板(如已设计好的合同、报表或证书)生成个性化 PDF,核心需求是:保留原模板的版式、字体、矢量图形和页面布局,仅在指定位置插入动态文本、图像或签名。此时,直接使用 FPDF 或 TCPDF 等纯生成类库并不适用——它们无法读取/复用现有 PDF 页面。正确方案是采用支持“导入 + 覆盖”能力的库,其中 FPDI(Free PDF Importer) 是最成熟、稳定且广泛使用的开源选择。
FPDI 并非独立 PDF 生成器,而是 FPDF/TCPDF 的扩展插件,它允许你:
- 加载任意 PDF 文件作为源模板;
- 读取其页面数量与尺寸;
- 将指定页面作为背景导入到新文档中;
- 在其上使用 FPDF/TCPDF 的绘图与文字方法进行精准叠加。
✅ 推荐技术栈组合:FPDI + FPDF(轻量级)或 FPDI + TCPDF(功能更全,支持 Unicode/中文)。
以下是一个完整、可运行的示例(基于 FPDI v2 + FPDF):
采用.NET CLR2.0、VS2005及SQL2000,前台页面使用用DIV+CSS开发;可以使用动态化运行,也可以采用全部静态化动作,甚至自己定义模板;后台信息编辑器采用最新版FCKeditor;产品信息可导出为EXCEL、WORD、PDF等格式存储;产品信息可以通过EXCEL模板批量导入;产品分类采用无限级分类;产品图片上传支持图片水印和文字水印,同时支持自动生成缩略图功能;电子邮件发送支持
立即学习“PHP免费学习笔记(深入)”;
setSourceFile($templatePath);
$pageId = $pdf->importPage(1, PdfReader\PageBoundaries::MEDIA_BOX);
// 添加新页面(尺寸与模板页一致)
$pdf->addPage();
// 将模板页作为背景绘制(x=10, y=10, width=90mm;单位默认为 mm)
$pdf->useImportedPage($pageId, 10, 10, 90);
// ✅ 在模板上方叠加动态内容(例如填写客户姓名、金额)
$pdf->SetFont('Helvetica', '', 12);
$pdf->SetTextColor(0, 0, 0);
$pdf->SetXY(100, 65); // 精确坐标需根据模板实际位置调试
$pdf->Cell(0, 0, '张三先生', 0, 1);
$pdf->SetXY(100, 80);
$pdf->Cell(0, 0, '¥12,800.00', 0, 1);
// 输出 PDF(I=浏览器预览,D=强制下载,F=保存到服务器)
$pdf->Output('D', 'invoice_2024_' . date('YmdHis') . '.pdf');⚠️ 关键注意事项:
- 安全第一:务必校验上传文件类型(mime_content_type() + 文件头检测)、重命名临时文件、禁止执行权限,并限制上传目录不可被 Web 直接访问;
- 中文支持:FPDF 默认不支持 UTF-8 中文。如需显示中文,请改用 TCPDF 作为底层引擎,并加载支持 GBK/UTF-8 的 TrueType 字体(如 simhei.ttf);
- 坐标调试:SetXY() 坐标需结合模板实际尺寸反复测试,建议先用 PDF 查看器测量关键字段的左上角坐标(单位:mm);
- 性能提示:FPDI 导入复杂模板(含大量矢量图/透明层)可能较慢,生产环境建议缓存模板解析结果(如预解析后存为序列化对象);
- 替代方案参考:若需同时支持 Word(.docx)模板,可考虑 PHPWord + TemplateProcessor;但 PDF 场景下 FPDI 仍是事实标准。
总结:从零开始实现模板 PDF 动态生成,应首选 FPDI 生态。它学习成本低、社区完善、无外部服务依赖,适合绝大多数企业级 PDF 填充需求。只需三步:安装 → 导入模板 → 叠加内容 → 输出,即可交付专业级结果。










