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

Java Apache PdfBox嵌入外部字体至PDF页面的实现方法咨询

在Apache PdfBox中嵌入并使用外部字体的完整方案

我经常帮人解决PdfBox相关的问题,嵌入外部字体这块其实流程很清晰,咱们一步步来:

1. 先搞定依赖和字体文件

首先确保你的项目里已经引入了PdfBox的依赖,如果你用Maven的话,在pom.xml里加这段:

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.32</version> <!-- 建议用最新稳定版 -->
</dependency>

然后把你要用到的外部字体文件(比如custom-font.ttf或者my-font.otf)放在项目的src/main/resources目录下,或者记好它的本地绝对路径。

2. 加载外部字体(核心步骤)

PdfBox推荐用PDType0Font来加载外部字体,它会自动处理字体嵌入,还支持子集嵌入(只嵌入用到的字符,减小PDF体积)。这里有两种加载方式:

从资源目录加载

如果字体在资源文件夹里,用输入流加载:

try (InputStream fontStream = YourClassName.class.getResourceAsStream("/custom-font.ttf")) {
    // 第二个参数设为true表示嵌入字体
    PDType0Font customFont = PDType0Font.load(document, fontStream, true);
} catch (IOException e) {
    e.printStackTrace();
}

从本地文件路径加载

如果字体在本地某个路径下:

File fontFile = new File("C:/fonts/custom-font.ttf");
try {
    PDType0Font customFont = PDType0Font.load(document, fontFile, true);
} catch (IOException e) {
    e.printStackTrace();
}

注意:别用PDTrueTypeFont了,它是旧的API,而且不支持子集嵌入,生成的PDF会更大。

3. 在PDF页面中使用嵌入的字体

分两种场景给你示例:

场景1:创建全新的PDF并使用外部字体

完整的代码示例,用try-with-resources自动关闭资源,避免内存泄漏:

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;

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

public class EmbedFontExample {
    public static void main(String[] args) {
        // 创建新PDF文档
        try (PDDocument document = new PDDocument()) {
            PDPage page = new PDPage();
            document.addPage(page);

            // 加载外部字体
            try (InputStream fontStream = EmbedFontExample.class.getResourceAsStream("/custom-font.ttf")) {
                PDType0Font customFont = PDType0Font.load(document, fontStream, true);

                // 创建内容流,开始写内容
                try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
                    // 设置字体和字号
                    contentStream.setFont(customFont, 12);
                    // 绘制文本,坐标(x=100, y=700),PDF的坐标原点在左下角
                    contentStream.beginText();
                    contentStream.newLineAtOffset(100, 700);
                    contentStream.showText("这是用外部嵌入字体写的文本!");
                    contentStream.endText();
                }
            }

            // 保存PDF
            document.save(new File("output-with-custom-font.pdf"));
            System.out.println("PDF生成成功,字体已嵌入!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

场景2:修改现有PDF,在页面中添加带外部字体的文本

如果你要给已有的PDF加内容,代码大概是这样:

try (PDDocument document = PDDocument.load(new File("existing-document.pdf"))) {
    PDPage page = document.getPage(0); // 获取第一页(索引从0开始)

    try (InputStream fontStream = YourClassName.class.getResourceAsStream("/custom-font.ttf")) {
        PDType0Font customFont = PDType0Font.load(document, fontStream, true);

        try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
            contentStream.setFont(customFont, 14);
            contentStream.beginText();
            contentStream.newLineAtOffset(150, 600);
            contentStream.showText("给现有PDF添加的外部字体文本");
            contentStream.endText();
        }
    }

    document.save(new File("modified-document.pdf"));
} catch (IOException e) {
    e.printStackTrace();
}

4. 一定要注意的几个点

  • 字体版权:不是所有字体都允许嵌入,有些商业字体有版权限制,使用前要确认授权!
  • 子集嵌入:加载字体时第三个参数设为true就会自动启用子集嵌入,只嵌入你用到的字符,能大幅减小PDF体积。如果设为false会嵌入整个字体文件,PDF会很大。
  • 资源关闭:所有的流(字体流、内容流、文档)都要记得关闭,用try-with-resources是最稳妥的方式,不用手动写close()。
  • 字符支持:如果你的字体不支持中文或者其他特殊字符,那显示会有问题,要选对应字符集的字体。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:34:08