You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 12:17:40