如何在动态生成PDF中嵌入信息,指引第三方程序指定位置放图片
解决方案:低负载实现PDF最后一页QR码坐标传递
一、嵌入自定义元数据方案的可行性
完全可行,且是低负载方案的优选之一。PDF的元数据(文档信息字典、XMP元数据)存储在文件头部区域,无需读取完整PDF即可提取,不会造成服务器负载压力。
实现示例(PHP+TCPDF)
生成PDF时直接写入自定义元数据:
$pdf = new TCPDF(); // 完成发票内容生成后 $totalPages = $pdf->getNumPages(); // 计算最后一页QR码坐标(示例:右下角,距边距20,QR码尺寸100) $pageWidth = $pdf->getPageWidth(); $pageHeight = $pdf->getPageHeight(); $qrX = $pageWidth - 20 - 100; $qrY = $pageHeight - 20 - 100; // 添加自定义元数据到文档信息字典 $pdf->setCustomProperty('LastPageQR', json_encode([ 'x' => $qrX, 'y' => $qrY, 'page' => $totalPages ])); // 输出PDF到字符串(用于后续上传)或临时文件 $pdfContent = $pdf->output('', 'S');
快速提取元数据的方式
无需加载完整PDF,用轻量工具或库即可读取:
- 命令行工具(qpdf):
qpdf --show-custom-properties invoice.pdf - PHP库(smalot/pdfparser,仅读取头部信息):
$parser = new \Smalot\PdfParser\Parser(); $pdf = $parser->parseContent($pdfContent); $qrMeta = json_decode($pdf->getDetails()['Custom']['LastPageQR'], true);
二、其他低负载解决方案
1. 生成时直接记录坐标到缓存/数据库
这是性能最优的方案:
- 生成PDF过程中,直接计算好最后一页的QR码坐标,将坐标与发票唯一标识(如订单ID、PDF哈希值)关联,存入Redis或数据库。
- 调用第三方API时,直接从缓存/数据库取出坐标,无需接触PDF文件,完全避免PDF解析开销。
2. 生成后直接处理临时文件,无需持久化
调整原有输出逻辑,先生成PDF到内存临时文件或磁盘临时文件:
- 生成时记录坐标,然后直接用临时文件上传至第三方API,上传完成后立即删除临时文件。
- 无需搭建第二台存储服务器,也无需后续解析PDF,流程更简洁。
示例(PHP直接上传):
// 生成PDF到临时文件 $tempFile = tempnam(sys_get_temp_dir(), 'invoice_'); $pdf->output($tempFile, 'F'); // 调用第三方API,传递临时文件和预计算的坐标 $ch = curl_init('https://third-party-api.com/stamp'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, [ 'pdf' => new CURLFile($tempFile), 'qr_x' => $qrX, 'qr_y' => $qrY ]); curl_exec($ch); // 删除临时文件 unlink($tempFile);
3. 在PDF最后页嵌入不可见标记文本
生成时在最后一页的固定位置写入不可见的文本标记(如{{QR_POS:x=100,y=200}}),后续用PDF工具仅扫描最后一页内容提取标记。这种方式比元数据稍复杂,但也无需读取完整PDF。
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 缓存/数据库存坐标 | 性能最优,无PDF解析开销 | 需维护标识与坐标的关联 |
| 自定义元数据 | 标准合规,不影响PDF内容 | 需确保元数据不被篡改 |
| 临时文件直接处理 | 流程简化,无额外存储 | 需管理临时文件生命周期 |
内容的提问来源于stack exchange,提问作者Ibnu Alam
相关产品推荐
相关产品推荐

