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

PHP环境下如何为已签名/认证PDF添加文本?FPDF&FPDI遇阻

问题:处理加密/签名PDF时FPDI报错的解决方案

我尝试用FPDF和FPDI给目标PDF添加文本时,触发了以下报错:

CrossReferenceException: This PDF document is encrypted and cannot be processed with FPDI.

我的完整PHP代码如下:

<?php
$servpath = getcwd();

require_once('app/ThirdParty/fpdf/fpdf.php');
require_once('app/ThirdParty/fpdi/src/autoload.php');

use setasign\Fpdi\Fpdi;

try {
    // 初始化FPDF对象
    $pdf = new Fpdi();

    // 添加现有PDF的页面
    $existingPdfPath = $servpath.'/files/project_files/7/imm5409e.pdf';
    $pdf->setSourceFile($existingPdfPath);
    $existingPdfPage = $pdf->importPage(1); // 导入现有PDF的第一页

    $pdf->AddPage();
    $pdf->useTemplate($existingPdfPage);

    // 在第一页添加文本
    $pdf->SetFont('Arial', 'B', 12);
    $pdf->SetTextColor(255, 0, 0); // 红色文本
    $pdf->SetXY(50, 50); // 设置文本位置
    $pdf->Cell(100, 10, 'IRCC First Name', 0, 1, 'C'); // 添加文本

    // 输出或保存修改后的PDF
    $outputPdfPath = $servpath.'/files/project_files/7/imm5409e-output.pdf';
    $pdf->Output($outputPdfPath, 'F');

    echo '文本已成功添加到PDF。';
} catch (setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException $e) {
    echo 'CrossReferenceException: ' . $e->getMessage();
} catch (setasign\Fpdi\PdfParser\PdfParserException $e) {
    echo 'PdfParserException: ' . $e->getMessage();
} catch (Exception $e) {
    echo '发生错误: ' . $e->getMessage();
}
?>

之后我尝试移除PDF保护,但因为文档已签名/认证,无法修改安全设置,提示:

You cannot change security on this document because the document is signed or certified.

目前我找到一个临时方法:在浏览器打开PDF后通过「打印->另存为PDF」得到的文件可以用PHP(FPDF&FPDI)编辑,但想找更优的动态添加文本方案,请问有可行办法吗?


可行解决方案

1. 用Ghostscript自动处理PDF(服务器端批量操作)

Ghostscript可以直接将加密或签名的PDF转换为无保护的扁平化版本,之后就能正常用FPDI编辑。

在服务器上执行以下命令(可以用PHP的exec()调用):

gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=unprotected.pdf -dPDFSETTINGS=/default your-protected.pdf

PHP里集成的示例:

$protectedPdf = $servpath.'/files/project_files/7/imm5409e.pdf';
$unprotectedPdf = $servpath.'/files/project_files/7/imm5409e-unprotected.pdf';

// 调用Ghostscript处理
exec("gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile={$unprotectedPdf} -dPDFSETTINGS=/default {$protectedPdf}");

// 之后用原代码操作$unprotectedPdf即可

2. 换用TCPDF替代FPDI

TCPDF对加密PDF的兼容性比FPDI更好,同样支持导入现有PDF页面并添加文本,示例代码:

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

$pdf = new TCPDF();
$pdf->AddPage();

// 导入现有PDF页面
$pageId = $pdf->setSourceFile($servpath.'/files/project_files/7/imm5409e.pdf');
$tplIdx = $pdf->importPage($pageId);
$pdf->useTemplate($tplIdx);

// 添加文本
$pdf->SetFont('helvetica', 'B', 12);
$pdf->SetTextColor(255, 0, 0);
$pdf->SetXY(50, 50);
$pdf->Cell(100, 10, 'IRCC First Name', 0, 1, 'C');

// 保存输出
$pdf->Output($servpath.'/files/project_files/7/imm5409e-output.pdf', 'F');
?>

3. 使用PDFtk Server(需服务器支持)

如果服务器允许安装PDFtk,可以用它解除PDF限制,命令示例:

pdftk your-protected.pdf output unprotected.pdf allow

注意:签名文档执行此操作后会丢失签名有效性,这是正常的——因为签名的核心作用就是防止篡改,任何修改都会破坏签名。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:27:12