使用Apache PDFBox 2.0.24在PDF同一页面插入文本与图片的问题求助
解决Apache PDFBox 2.0.24同一页面同时插入图片与文本的问题
我之前也踩过这个坑!你遇到的图片消失问题,核心原因几乎都是没有正确使用内容流的追加模式——默认情况下,创建PDPageContentStream会直接覆盖页面原有内容,包括你刚插入的图片。只要调整内容流的初始化方式,就能同时保留图片和文本。
核心思路
PDFBox中,操作现有页面时必须指定AppendMode.APPEND模式创建内容流,这样新的绘制指令会追加到页面原有内容之后,而不是覆盖掉之前的所有内容。不管是分两次添加图片和文本,还是在同一个内容流里完成操作,都要遵循这个原则。
完整代码示例
方式1:分两次追加内容(先图后文)
这种方式适合需要分开处理图片和文本逻辑的场景:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.pdmodel.font.PDType1Font; import java.io.File; import java.io.IOException; public class AddImageAndText { public static void main(String[] args) { try (PDDocument doc = PDDocument.load(new File("your-existing-file.pdf"))) { // 获取目标页面(这里取第一页,按需调整索引) PDPage targetPage = doc.getPage(0); // 1. 插入图片:使用APPEND模式创建内容流 try (PDPageContentStream stream = new PDPageContentStream(doc, targetPage, PDPageContentStream.AppendMode.APPEND, true)) { PDImageXObject image = PDImageXObject.createFromFile("your-image.png", doc); // 图片位置:左下角(x=100, y=500),宽200,高150(PDF坐标原点在左下角) stream.drawImage(image, 100, 500, 200, 150); } // 2. 插入文本:同样使用APPEND模式 try (PDPageContentStream stream = new PDPageContentStream(doc, targetPage, PDPageContentStream.AppendMode.APPEND, true)) { stream.setFont(PDType1Font.HELVETICA, 14); stream.setNonStrokingColor(0, 0, 0); // 黑色文本 stream.beginText(); stream.newLineAtOffset(100, 480); // 文本放在图片下方 stream.showText("这是和图片共存的文本内容"); stream.endText(); } // 保存修改后的PDF doc.save("modified-file.pdf"); } catch (IOException e) { e.printStackTrace(); } } }
方式2:同一内容流完成所有操作(更高效)
如果图片和文本的逻辑可以放在一起,用同一个内容流处理更简洁:
try (PDPageContentStream stream = new PDPageContentStream(doc, targetPage, PDPageContentStream.AppendMode.APPEND, true)) { // 先绘制图片 PDImageXObject image = PDImageXObject.createFromFile("your-image.png", doc); stream.drawImage(image, 100, 500, 200, 150); // 紧接着绘制文本 stream.setFont(PDType1Font.TIMES_ROMAN, 14); stream.setNonStrokingColor(0, 0, 0); stream.beginText(); stream.newLineAtOffset(100, 480); stream.showText("同一内容流添加的文本"); stream.endText(); }
关键注意事项
- 必须指定追加模式:不要省略
PDPageContentStream.AppendMode.APPEND参数,默认的OVERWRITE会直接清空页面原有内容。 - 资源自动关闭:用
try-with-resources语法包裹内容流,避免资源泄漏导致的异常。 - PDF坐标规则:PDF的坐标原点在页面左下角,y轴向上递增,设置位置时要注意不要超出页面范围。
- 字体选择:如果使用自定义字体,要确保字体文件路径正确;也可以直接用PDFBox自带的
PDType1Font系列字体(如HELVETICA、TIMES_ROMAN),无需额外文件。
内容的提问来源于stack exchange,提问作者Senura
相关产品推荐
相关产品推荐

