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

Java生成PDF字体加载异常:IDE正常打包exe后报错找不到字体文件

Java打包为exe后iTextPDF加载自定义字体失败问题解决

问题描述

IDE环境运行生成PDF的程序一切正常,但打包为.exe后,提示css/Montserrat-Regular.ttf not found错误,无法生成PDF。已尝试移除css/路径、将字体文件放置在类同目录下,且确认字体文件已包含在IntelliJ IDEA的构建产物中。

环境依赖与导入

依赖配置

implementation 'com.itextpdf:itext7-core:7.0.4'

导入包

import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.pdf.PdfDocument;

已尝试的无效加载方式

  • 方式一:资源流转字节数组加载
static PdfFont regular, bold;

URL font_path = Thread.currentThread().getContextClassLoader().getResource("css/Montserrat-Regular.ttf");
try (InputStream is = font_path.openStream()) {
    byte[] bytes = StreamUtil.inputStreamToArray(is);
    regular = PdfFontFactory.createFont(bytes, BaseFont.IDENTITY_H, true);
}
  • 方式二:类加载器获取路径加载
String link1 = Thread.currentThread().getContextClassLoader().getResource("css/Montserrat-Regular.ttf").getPath();
regular = PdfFontFactory.createFont(link1, BaseFont.IDENTITY_H, true);
  • 方式三:使用iText内置字体
regular = PdfFontFactory.createFont(FontConstants.HELVETICA, BaseFont.IDENTITY_H, true);
bold = PdfFontFactory.createFont(FontConstants.TIMES_BOLD, BaseFont.IDENTITY_H, true);
  • 方式四:通过类的类加载器获取路径加载
String path1 = (CreatePDFInvoice.class.getClassLoader().getResource("css/Montserrat-Regular.ttf").getPath());
regular = PdfFontFactory.createFont(path1, "Identity-H", true);

相关代码片段

try {
    String link1 = CreatePDFKUF.class.getClassLoader().getResource("css/Montserrat-Regular.ttf").getPath();
    String link2 = CreatePDFKUF.class.getClassLoader().getResource("css/Montserrat-Bold.ttf").getPath();

    // 弹出对话框显示路径
    Functions.showOKdialogSimple("Upute", null, link1);

    // 此处触发错误
    regular = PdfFontFactory.createFont(link1, BaseFont.IDENTITY_H, true);

    String folder = Functions.odabranaFirma.getNaziv();
    String subfolder = "KIF";
    String filename = Functions.odabranaFirma.getPDV_broj() + "_" + poreskiPeriod;
    theDir = new File("C:\\CSV_PDV\\" + folder + "\\" + subfolder + "\\");

    System.out.println(theDir.getPath());

    if (!theDir.exists()) {
        System.out.println("Kreiraj");
        theDir.mkdirs();
    }

    String path = "C:/CSV_PDV/" + filename + "_" + LocalDate.now() + "_" + String.valueOf(Functions.getTime()).replace(":", "") + ".pdf";
    System.out.println("Naziv datoteke " + path);
    PdfWriter pdfWriter = new PdfWriter(path);
    PdfDocument pdfDocument = new PdfDocument(pdfWriter);
    pdfDocument.setDefaultPageSize(PageSize.A4.rotate());

    Document document = new Document(pdfDocument);

    PageXofY event = new PageXofY(CreatePDFKUF.class, pdfDocument);
    pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, event);

    setHeader(document);
    setDetails(document, poreskiPeriod);
    setTable(document, kufs);
    document.add(sp);
    document.add(sp);
    UnitValue pagesize = document.getWidth();
    System.err.println(pagesize + " page size");

    event.writeTotal(pdfDocument);
    document.close();

} catch (Exception e) {
    // 弹出错误对话框显示异常信息
    Functions.showOKdialogSimple("Greška", null, e.getMessage());
}

报错截图

  • 路径显示对话框:路径显示对话框
  • 错误提示对话框:错误提示对话框

解决方案

核心问题

打包为exe后,资源文件内嵌在exe/jar包中,无法通过文件系统路径直接访问;类加载器getPath()返回的路径包含特殊协议前缀(如file:/)和转义字符,PdfFontFactory无法解析。

正确字体加载代码

直接通过资源输入流读取字体,完全脱离文件路径依赖:

static PdfFont regular, bold;

try (InputStream regularIs = CreatePDFKUF.class.getClassLoader().getResourceAsStream("css/Montserrat-Regular.ttf");
     InputStream boldIs = CreatePDFKUF.class.getClassLoader().getResourceAsStream("css/Montserrat-Bold.ttf")) {

    if (regularIs == null || boldIs == null) {
        throw new RuntimeException("字体文件未找到,请确认资源路径是否正确");
    }

    // 直接传入输入流创建字体
    regular = PdfFontFactory.createFont(regularIs, BaseFont.IDENTITY_H, true);
    bold = PdfFontFactory.createFont(boldIs, BaseFont.IDENTITY_H, true);

} catch (IOException e) {
    e.printStackTrace();
    throw new RuntimeException("加载字体失败:" + e.getMessage());
}

额外注意事项

  1. 资源目录规范:确保css文件夹放在src/main/resources目录下(IntelliJ IDEA会自动将该目录内容打包到classpath)。
  2. 打包配置检查:使用exe打包工具(如Launch4j、Inno Setup)时,确认jar包内的资源文件被完整内嵌,未遗漏resources目录内容。
  3. 版本建议:将iText7版本升级至7.2.0+,修复了旧版本中部分资源加载的兼容性问题。

内容的提问来源于stack exchange,提问作者Armin Brkić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 08:17:48