使用FPDF/FPDI+GhostScript处理PDF时添加13条记录后首页被覆盖求助
问题排查与解决方案
1. 临时文件冲突(最可能的根源)
你当前使用固定名称的临时文件tempInstruireSuplimentara.pdf和temp2InstruireSuplimentara.pdf,处理第13条记录时,新生成的文件会直接覆盖之前的临时文件。如果合并逻辑还在依赖旧的临时文件内容,就会导致首页被最新的文件替换。
解决方法:
为每条记录生成唯一的临时文件名,比如结合记录ID或时间戳:
// 生成唯一临时文件名 $tempFile = "C:/xampp/htdocs/survey_v1/temp/tempInstruire_" . uniqid() . ".pdf"; $tempFile2 = "C:/xampp/htdocs/survey_v1/temp/temp2Instruire_" . uniqid() . ".pdf"; file_put_contents($tempFile, $row['file']); shell_exec( "gswin64 -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=\"{$tempFile2}\" \"{$tempFile}\"" ); $pageCount = $pdfI->setSourceFile($tempFile2); // 处理完成后删除临时文件,避免磁盘占用 unlink($tempFile); unlink($tempFile2);
2. FPDI实例化与页面导入逻辑错误
如果是循环处理13条记录,错误的实例化时机或页面导入逻辑会导致首页被覆盖:
- 确保主
Fpdi对象在循环外初始化,循环内仅做页面导入和添加:
// 循环外初始化主PDF对象 $pdfI = new \setasign\Fpdi\Fpdi(); $pdfI->SetAutoPageBreak(false); foreach ($records as $row) { // 生成唯一临时文件 $tempFile = "C:/xampp/htdocs/survey_v1/temp/temp_" . uniqid() . ".pdf"; $tempFile2 = "C:/xampp/htdocs/survey_v1/temp/temp2_" . uniqid() . ".pdf"; file_put_contents($tempFile, $row['file']); shell_exec( "gswin64 -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=\"{$tempFile2}\" \"{$tempFile}\"" ); $pageCount = $pdfI->setSourceFile($tempFile2); // 导入当前PDF的所有页面并添加到主文档 for ($i = 1; $i <= $pageCount; $i++) { $tplIdx = $pdfI->importPage($i); $size = $pdfI->getTemplateSize($tplIdx); $pdfI->AddPage($size['orientation'], [$size['width'], $size['height']]); $pdfI->useTemplate($tplIdx); } unlink($tempFile); unlink($tempFile2); } // 输出合并后的PDF $pdfI->Output('merged_result.pdf', 'F');
- 确认每次导入页面时,都调用
importPage和AddPage,而非直接覆盖已有页面。
3. GhostScript转换异常
检查转换后的PDF是否本身存在问题:
- 手动执行GhostScript命令,查看转换后的
temp2文件是否能正常打开,首页内容是否完整:
gswin64 -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH -sOutputFile="temp2.pdf" "temp.pdf"
- 去掉
-dQUIET参数,查看转换过程中是否有错误提示,根据提示调整参数(比如添加-dPDFSETTINGS=/prepress)。
4. 文件权限与写入完整性
确保临时目录有读写权限,在file_put_contents后验证文件是否正常生成:
if (!file_exists($tempFile) || filesize($tempFile) === 0) { // 处理文件写入失败的情况,比如跳过当前记录或抛出提示 continue; }
内容的提问来源于stack exchange,提问作者georgelaurentiu
相关产品推荐
相关产品推荐

