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

使用PDFBox在无AcroForm的特殊尺寸PDF中添加文本不显示问题

解决PDFBox添加文本不显示的问题

首先,你的代码逻辑本身没问题,但文本没显示大概率是文本位置超出了页面可视范围——毕竟你处理的是名片尺寸的PDF,常规A4的Y坐标(比如400)在小尺寸页面上可能已经跑到页面外面去了。另外还有几个细节可以优化,我帮你梳理一下:

核心问题:页面坐标系与实际尺寸不匹配

PDF的坐标系原点在页面左下角,而名片的尺寸(比如常见的90mm×55mm,换算成PDF单位约324×198点)远小于A4的842×595点。你设置的newLineAtOffset(100, 400),Y坐标400已经远超名片的高度,文本自然看不到。

解决方法:先获取页面的实际尺寸,再根据尺寸计算合适的坐标:

PDPage page = document.getPage(0);
PDRectangle pageSize = page.getMediaBox();
float pageWidth = pageSize.getWidth();
float pageHeight = pageSize.getHeight();
// 比如在页面垂直居中、水平靠左的位置开始写文本,Y坐标设为pageHeight - 50(留50点边距)
content.newLineAtOffset(20, pageHeight - 50);

其他需要注意的细节

  • 追加模式的图层问题:你用的AppendMode.APPEND是把新内容加到现有内容后面,如果原PDF有背景层覆盖,可能会看不到新文本。可以改成AppendMode.PREPEND把文本放在最上层,或者确认原PDF没有遮挡:
    PDPageContentStream content = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, true);
    
  • 行距设置:newLine()默认的行距是字体大小的1.2倍,但如果你用30号字体,最好手动设置行距,避免文本重叠:
    content.setLeading(36); // 设置行距为36点,比30号字体大一点
    
  • 代码规范:不需要强制转换PDPage,直接用document.getPage(0)即可。

修正后的完整代码

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.PDPageContentStream;

import java.io.File;
import java.io.IOException;

public class FillBusinessCard {
    public static void main(String[] args) {
        try {
            File file = new File("ToBeFilled.pdf");
            PDDocument document = PDDocument.load(file);
            System.out.println("PDF loaded");

            PDPage page = document.getPage(0);
            // 获取页面实际尺寸
            PDRectangle pageSize = page.getMediaBox();
            float pageWidth = pageSize.getWidth();
            float pageHeight = pageSize.getHeight();
            System.out.println("页面尺寸:宽=" + pageWidth + ", 高=" + pageHeight);

            PDFont font = PDType1Font.HELVETICA_BOLD;
            // 用PREPEND模式确保文本在最上层
            PDPageContentStream content = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, true);

            content.beginText();
            content.setFont(font, 30);
            // 设置行距
            content.setLeading(36);
            // 调整坐标到页面内,比如左边距20,上边距50
            content.newLineAtOffset(20, pageHeight - 50);

            String text = "张三";
            String text1 = "1990-01-01";
            String text2 = "软件工程师";

            content.showText(text);
            content.newLine();
            content.showText(text1);
            content.newLine();
            content.showText(text2);

            content.endText();
            System.out.println("Text added");

            content.close();
            document.save("newPrint.pdf");
            document.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

额外建议

  • 如果你需要精确对应名片上的固定位置,可以用PDF阅读器(比如Adobe Acrobat)打开原PDF,查看目标位置的坐标(一般阅读器的测量工具可以显示坐标),然后直接用对应的x、y值。
  • 对于非Type1字体,需要确保字体嵌入正确,但你用的HELVETICA_BOLD是内置字体,不用担心嵌入问题。

内容的提问来源于stack exchange,提问作者LLeif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:51:29