使用TCPDF、Ghostscript、FPDI处理PDF时如何保留SVG上的点击链接
问题根源
你遇到的链接失效是两个环节共同导致的:
- 第一,Ghostscript默认转换PDF时如果没有配置保留交互元素的参数,会过滤掉PDF内的链接批注
- 第二,开源版FPDI本身仅支持导入PDF的页面内容流,所有交互元素(包括链接、批注、表单域等)都不会被导入,哪怕Ghostscript保留了链接,经过FPDI合并后也会丢失
方案1(最推荐,开源可实现,无需修改现有工具链)
调整加链接的时机,把加链接的操作放到所有PDF处理步骤的最后,手动在对应位置添加链接批注:
你之前插入SVG时的坐标、尺寸是已知的(代码里是x=0, y=0,宽高为SVG原始尺寸),只需要在FPDI合并完Logo之后、输出PDF之前,调用TCPDF的Link()方法在相同位置添加跳转链接即可。如果不知道SVG的宽高,可提前读取SVG文件的属性获取,修改后的FPDI部分代码如下:
// 原有合并Logo的代码不变 if($logoselect == 'eng') { $logos = $pdf->setSourceFile( $path.'img/engadin_online_CMYK.pdf', 'F' ); $logo = $pdf->ImportPage( 1 ); $pdf->useTemplate( $logo, 34.25, 33.75, null, 32.5); } if($logoselect == 'gam') { $logos = $pdf->setSourceFile( $path.'img/gammetermedia_CMYK.pdf', 'F' ); $logo = $pdf->ImportPage( 1 ); $pdf->useTemplate( $logo, 34.25, 33.75, null, 32.5); } // 新增:读取SVG宽高,在原SVG的位置手动添加链接 $svg = simplexml_load_file($fullPath); $svgWidth = (float)$svg['width']; $svgHeight = (float)$svg['height']; // Link参数依次为:X坐标、Y坐标、宽度、高度、跳转链接,和你之前调用ImageSVG时的参数保持一致即可 $pdf->Link(0, 0, $svgWidth, $svgHeight, $query); // 原有输出代码不变 $base = $pdf->Output('qrcode.pdf', 'E');
这个方案完全规避了中间步骤丢链接的问题,稳定性最高,不需要修改Ghostscript和FPDI的配置。
方案2(保留原流程,需要额外配置或付费)
如果你一定要在生成初始PDF时就加链接,需要修改两个环节的配置:
- 给Ghostscript命令添加保留批注的参数,修改后的Ghostscript代码如下:
$process = new Process(['gs', '-o', $path.'pdf/'.$uniqname.'.pdf', '-sDEVICE=pdfwrite', '-sColorConversionStrategy=Gray', '-dProcessColorModel=/DeviceGray', '-dCompatibilityLevel=1.4', '-dOverrideICC=true', '-dPreserveAnnots=true', "-sDefaultCMYKProfile=$iccFile", $targetFile]);
新增的-dPreserveAnnots=true参数会让Ghostscript在转换格式时保留PDF内的链接批注。
2. 处理FPDI丢失链接的问题,有两个选择:
- 更换PDF合并工具:使用pdftk等支持保留交互元素的工具合并PDF,无需改动现有代码逻辑
- 升级为商业版FPDI:官方商业版的FPDI Parser支持导入PDF的交互元素,包括链接批注
内容的提问来源于stack exchange,提问作者madebyjo_l
相关产品推荐
相关产品推荐

