Laravel中借助FPDI/FPDF能否读取PDF位置并在原有内容后追加内容?
在Laravel中用FPDI/FPDF向PDF最后一页添加内容
没问题!你完全可以在现有PDF最后一页的内容之后添加新内容,不需要新增页面或者留白,但有个关键前提要先说明:FPDI本身没办法直接检测导入PDF页面里现有内容的实际边界——它只是把原页面当作一个图像模板导入,没法解析原PDF里的文本、元素坐标。不过我们可以通过两种思路来实现需求:
思路1:已知原页面内容的固定结束位置
如果你的目标PDF最后一页的布局是固定的(比如知道内容结束的Y坐标),那可以直接在导入模板后,定位到该坐标开始写入新内容。
示例代码
$pdf = new \setasign\Fpdi\Fpdi('L','mm','A4'); $url = 'your-target.pdf'; // 替换为你的PDF文件路径 $pageCount = $pdf->setSourceFile(public_path($url)); $pdf->setFont('Arial', 'B', 10); for($i = 1; $i <= $pageCount; $i++){ $tplIdx = $pdf->importPage($i); $pageDimensions = $pdf->getImportedPageSize($tplIdx); $pdf->addPage($pageDimensions['orientation'], $pageDimensions); $pdf->useTemplate($tplIdx); // 仅在最后一页执行添加逻辑 if($i === $pageCount) { // 假设横向A4页面中,原内容结束在190mm的Y位置(从页面顶部开始计算) $pdf->SetY(190); $pdf->SetX(20); // 设置内容的左侧偏移量,可根据需求调整 $pdf->Cell(0, 5, '这是添加在现有内容之后的新文本', 0, 1); // 如果需要自动换行的长文本,使用MultiCell方法 $pdf->MultiCell(0, 5, '这是一段需要自动换行的长内容,会从设定的坐标开始写入,不会超出页面或者新增分页(需确保剩余空间足够)', 0, 'L'); } } // 输出PDF到浏览器('I'表示在线预览,'F'表示保存到服务器) $pdf->Output('updated-pdf.pdf', 'I');
思路2:动态检测原内容的结束位置(需额外依赖)
如果不知道原内容的结束位置,需要先解析PDF获取最后一段内容的坐标,再定位写入。这时候需要用到能解析PDF内容的第三方库,比如smalot/pdfparser。
步骤1:安装依赖
在Laravel项目中执行Composer命令安装:
composer require smalot/pdfparser
示例代码
// 先解析PDF,获取最后一页最后一段内容的坐标 $parser = new \Smalot\PdfParser\Parser(); $pdfParser = $parser->parseFile(public_path($url)); $pages = $pdfParser->getPages(); $lastPage = end($pages); $textElements = $lastPage->getTexts(); $lastText = end($textElements); // 转换坐标:PDF默认原点在左下角,FPDI默认原点在左上角,需转换为FPDI的Y坐标 // 横向A4页面的高度为210mm,所以顶部Y坐标为210,底部为0 $lastContentBottomY = 210 - $lastText['bbox'][3]; // bbox格式为[x1, y1, x2, y2],y2是内容左下角的Y值 // 用FPDI导入并添加内容 $pdf = new \setasign\Fpdi\Fpdi('L','mm','A4'); $pageCount = $pdf->setSourceFile(public_path($url)); $pdf->setFont('Arial', 'B', 10); for($i = 1; $i <= $pageCount; $i++){ $tplIdx = $pdf->importPage($i); $pageDimensions = $pdf->getImportedPageSize($tplIdx); $pdf->addPage($pageDimensions['orientation'], $pageDimensions); $pdf->useTemplate($tplIdx); if($i === $pageCount) { // 设置Y坐标为最后一段内容底部+5mm(留出间距) $pdf->SetY($lastContentBottomY + 5); $pdf->SetX(20); $pdf->Cell(0, 5, '动态定位的新增内容', 0, 1); } } $pdf->Output('updated-pdf.pdf', 'I');
注意事项
- 坐标转换:务必注意PDF和FPDI的坐标原点差异,避免定位错误。
- 兼容性:
smalot/pdfparser无法解析扫描版PDF(图片格式的PDF)或加密PDF,这类场景只能手动估算内容位置。 - 内容长度:如果新增内容超出页面剩余空间,FPDI会直接将内容溢出到页面外,不会自动分页,需确保内容长度适配剩余空间。
内容的提问来源于stack exchange,提问作者Mdr Kuchhadiya
相关产品推荐
相关产品推荐

