You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP 8.1中填充可填写PDF模板?适配Alpine 3.16容器

问题

给定一个可填写PDF,需从数据库获取数据填充至PDF,并允许用户下载。

上下文

  • PDF模板固定(必要时可预先手动修改)
  • PDF包含复选框
  • 运行环境:Alpine 3.16 Docker容器 + PHP 8.1
  • 禁止每次重新生成完整PDF
  • 无法提供具体PDF,仅为含文本输入框和复选框的普通可填写PDF

已尝试的无效方案

  • Dompdf:仅支持创建PDF,不支持表单填充
  • Setasign/FPDI:可导入PDF模板,但无表单填充功能
  • SetaPDF-FormFiller:功能可行但成本过高,不符合项目规模
  • tecnickcom/TCPDF:仅支持创建PDF,不支持填充
  • pdftk (Server):本地测试有效,但无法在Alpine容器部署
  • mikehaertl/php-pdftk:pdftk的PHP封装,同样存在Alpine部署问题
  • FPDF:不支持复选框表单元素
  • codeshell/fpdm:基于FPDF,支持复选框,但在PHP 8.1下失效,且已4年未维护
  • 转图片叠加文本方案:会丢失PDF表单的可编辑性,不符合需求
  • pdftk-java:暂未测试,但为该功能在每个Pod安装Java是最后备选方案

推荐解决方案

方案1:pdftk-java + PHP封装(优先推荐)

pdftk-java是pdftk的开源Java实现,可在Alpine容器中轻量部署,支持填充文本框、复选框等表单元素,完全免费,且与原pdftk命令兼容。

部署与实现:

  1. 在Dockerfile中添加依赖安装:
RUN apk add --no-cache openjdk17-jre-headless pdftk-java
  1. 使用PHP封装库调用pdftk-java,示例代码:
use mikehaertl\pdftk\Pdf;

// 加载PDF模板
$pdf = new Pdf('path/to/your-template.pdf');

// 构造表单数据(复选框值需匹配PDF模板中定义的勾选标识,通常为'Yes'/'Off'或自定义值)
$formData = [
    'user_fullname' => '张三',
    'accept_terms' => 'Yes', // 对应复选框勾选状态
    'contact_email' => 'zhangsan@example.com'
];

// 执行填充并输出下载
if ($pdf->fillForm($formData)->saveAs('/tmp/filled-output.pdf')) {
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename="filled-form.pdf"');
    readfile('/tmp/filled-output.pdf');
    unlink('/tmp/filled-output.pdf'); // 清理临时文件
    exit;
} else {
    die('填充失败:' . $pdf->getError());
}

方案2:社区维护版fpdm

原codeshell/fpdm虽停止维护,但社区存在修复了PHP 8.1兼容性的fork版本,可直接复用FPDF基础的表单填充逻辑,无需额外系统依赖,适合对容器体积要求严格的场景。

实现步骤:

  1. 引入兼容PHP 8.1的fpdm分支版本(通过Composer或手动下载源码)
  2. 示例填充代码:
require_once 'path/to/fpdm.php';

$pdf = new FPDM('path/to/your-template.pdf');
// 加载表单数据,复选框值需匹配模板定义(通常为'1'代表勾选)
$pdf->Load([
    'user_fullname' => '张三',
    'accept_terms' => '1',
    'contact_email' => 'zhangsan@example.com'
]);
$pdf->Merge();
// 直接输出供用户下载
$pdf->Output('filled-form.pdf', 'D');

方案3:LibreOffice命令行填充(备选)

若上述方案均不适用,可使用LibreOffice的命令行工具填充表单,Alpine容器中可安装轻量版LibreOffice,支持多种表单元素填充。

部署与实现:

  1. 在Dockerfile中安装依赖:
RUN apk add --no-cache libreoffice-writer libreoffice-pdfimport
  1. PHP中调用命令行执行填充:
$templatePath = 'path/to/your-template.pdf';
$outputDir = '/tmp/pdf-output';
mkdir($outputDir, 0777, true);

// 构造表单数据并写入临时JSON文件
$formData = json_encode([
    'user_fullname' => '张三',
    'accept_terms' => true
]);
$tempDataFile = '/tmp/form-data.json';
file_put_contents($tempDataFile, $formData);

// 执行LibreOffice填充命令
exec("libreoffice --headless --convert-to pdf --outdir {$outputDir} --fill-form {$tempDataFile} {$templatePath}");

// 输出下载响应
$filledPdfPath = $outputDir . '/' . basename($templatePath);
if (file_exists($filledPdfPath)) {
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename="filled-form.pdf"');
    readfile($filledPdfPath);
    // 清理临时文件
    unlink($tempDataFile);
    unlink($filledPdfPath);
    rmdir($outputDir);
    exit;
} else {
    die('填充失败:未生成目标文件');
}

内容的提问来源于stack exchange,提问作者Dylan Buth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:07:11