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
相关产品推荐
相关产品推荐

