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

PHP中如何扁平化含预填表单域的PDF并保留数据?

PHP扁平化预填PDF表单的替代方案

问题背景

我需要在将预填好的PDF表单发送至外部签名服务前,用PHP做扁平化处理。先后尝试了两个库都没达到预期:

1. php-pdftk库

执行代码:

<?php

require __DIR__ . '/vendor/autoload.php';

use mikehaertl\pdftk\Pdf;

($pdf = new Pdf('/app/pdf-prefilled.pdf'))->flatten()->saveAs('/app/pdf-flat.pdf');

echo $pdf->getError();

出现错误:

Unhandled Java Exception in create_output():
java.lang.ClassCastException: class pdftk.com.lowagie.text.pdf.PdfString cannot be cast to class pdftk.com.lowagie.text.pdf.PdfDictionary (pdftk.com.lowagie.text.pdf.PdfString and pdftk.com.lowagie.text.pdf.PdfDictionary are in unnamed module of loader 'app')
at pdftk.com.lowagie.text.pdf.PdfStamperImp.flatFields(PdfStamperImp.java:738)
at pdftk.com.lowagie.text.pdf.PdfStamperImp.close(PdfStamperImp.java:163)
at pdftk.com.lowagie.text.pdf.PdfStamperImp.close(PdfStamperImp.java:304)
at com.gitlab.pdftk_java.filter.create_output_filter(filter.java:424)
at com.gitlab.pdftk_java.TK_Session.create_output(TK_Session.java:1445)
at com.gitlab.pdftk_java.pdftk.main_noexit(pdftk.java:192)
at com.gitlab.pdftk_java.pdftk.main(pdftk.java:163)
There was a problem with pdftk-java. Please report it at
https://gitlab.com/pdftk-java/pdftk/issues
including the message above, the version of pdftk-java (3.2.2), and if possible steps to reproduce the error.Xdebug: [Step Debug] Time-out connecting to debugging clien

2. tcpdi库

能成功扁平化但丢失预填数据,且不支持解析表单域,代码:

<?php

use TCPDI;

$pdf = new TCPDI();
$pagecount = $pdf->setSourceData($data);
for ($i = 1; $i <= $pagecount; $i++) {
    $tplidx = $pdf->importPage($i);
    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);
    $pdf->AddPage();
    $pdf->importAnnotations($i);
    $pdf->useTemplate($tplidx);
}
$data = $pdf->Output('', 'S');

可行替代方案

1. FPDF + FPDI组合方案

借助FPDF和FPDI的组合,先解析PDF表单域的位置、字体等信息,再将预填数据直接绘制到PDF对应位置,实现扁平化。示例代码思路:

<?php
require_once('fpdf.php');
require_once('fpdi.php');

class PDF_Flatten extends FPDI {
    private $formData;

    public function setFormData($data) {
        $this->formData = $data;
    }
}

$pdf = new PDF_Flatten();
$pageCount = $pdf->setSourceFile('/app/pdf-prefilled.pdf');

// 通过pdftk的dump_data_fields命令解析表单域数据和位置,再转为数组
$formData = $this->parseFormFields('/app/pdf-prefilled.pdf');
$pdf->setFormData($formData);

for ($i = 1; $i <= $pageCount; $i++) {
    $tplIdx = $pdf->importPage($i);
    $size = $pdf->getTemplateSize($tplIdx);
    $pdf->AddPage($size['w'] > $size['h'] ? 'L' : 'P', array($size['w'], $size['h']));
    $pdf->useTemplate($tplIdx);
    
    // 遍历表单数据,在对应坐标绘制文本
    foreach ($formData as $field) {
        $pdf->SetFont($field['font'], '', $field['font_size']);
        $pdf->SetXY($field['x'], $field['y']);
        $pdf->Write(0, $field['value']);
    }
}

$pdf->Output('/app/pdf-flat.pdf', 'F');

关键是先通过命令行工具获取表单域的详细属性,再映射到PDF绘制逻辑中。

2. 调用Ghostscript命令行

利用Ghostscript的PDF处理能力,通过PHP执行shell命令实现扁平化,兼容性强且稳定。示例代码:

<?php
$inputFile = '/app/pdf-prefilled.pdf';
$outputFile = '/app/pdf-flat.pdf';

// Ghostscript扁平化命令
$command = "gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPreserveAnnots=false -sOutputFile={$outputFile} {$inputFile}";

exec($command, $output, $returnVar);

if ($returnVar !== 0) {
    echo "扁平化失败:" . implode("\n", $output);
} else {
    echo "扁平化成功";
}

注意:服务器需安装Ghostscript,且PHP需具备执行shell命令的权限。

3. TCPDF重绘方案

如果PDF是标准AcroForm,先解析表单域数据和位置,用TCPDF导入原PDF内容后,将预填数据绘制到对应位置,重新生成扁平化PDF。示例思路:

<?php
require_once('tcpdf.php');

// 解析表单域数据和位置(可通过pdftk dump_data_fields获取并解析)
$formFields = $this->getFormFields('/app/pdf-prefilled.pdf');

$pdf = new TCPDF();
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();

// 导入原PDF作为背景
$pdf->Image('/app/pdf-prefilled.pdf', 0, 0, 210, 297);

// 绘制表单数据
foreach ($formFields as $field) {
    $pdf->SetFont($field['font'], '', $field['font_size']);
    $pdf->SetXY($field['x'], $field['y']);
    $pdf->Write(0, $field['value']);
}

$pdf->Output('/app/pdf-flat.pdf', 'F');

此方案适合结构规范的PDF表单,需确保表单域属性解析准确。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 11:10:03