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

PDFBox 2.0.7处理国际字符时获取字符串宽度报错如何解决

问题根源

你使用的PDFBox内置标准14字体HELVETICA_BOLD默认采用WinAnsiEncoding编码,仅支持拉丁字母基础字符集,不包含U+0117(ė)这类扩展拉丁字符,因此调用getStringWidth时会抛出编码不支持的异常。

解决方案

  • 方案1:加载支持Unicode的外部TTF/OTF字体(推荐)
    放弃使用内置标准14字体,加载本地支持全字符集的字体文件(比如Arial Unicode MS、思源黑体等),使用PDType0Font加载即可支持国际化字符的宽度计算与渲染,示例代码:

    // 加载外部TTF字体文件,第二个参数设为true代表嵌入字体(如果后续需要渲染PDF建议开启)
    PDType0Font unicodeFont = PDType0Font.load(document, new File("path/to/your/font.ttf"), true);
    String myString = "Crėamė";
    float FONT_SIZE = 5.3f;
    float titleWidth = unicodeFont.getStringWidth(myString) / 1000 * FONT_SIZE;
    

    注意:此处document为你当前操作的PDDocument实例,需要保证pdfbox和fontbox依赖版本一致,避免加载字体时报错。

  • 方案2:字符转码兜底(仅适用于不需要精确显示、仅需近似宽度的场景)
    如果你暂时无法引入外部字体,可以先对字符串做转码处理,将WinAnsiEncoding不支持的字符替换为近似的基础字符,再计算宽度:

    // 去除字符的变音符号,转为基础拉丁字符
    String normalized = Normalizer.normalize(myString, Normalizer.Form.NFD);
    Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
    String asciiStr = pattern.matcher(normalized).replaceAll("");
    // 再用内置字体计算宽度
    float titleWidth = helveticaBold.getStringWidth(asciiStr) / 1000 * FONT_SIZE;
    
  • 方案3:使用AWT FontMetrics预计算宽度(仅需宽度不需要渲染PDF的场景)
    如果你只需要计算字符串宽度,不需要后续渲染到PDF,可以直接用AWT的字体工具类计算,不受PDFBox字体编码限制:

    java.awt.Font font = new java.awt.Font("Helvetica", java.awt.Font.BOLD, (int)FONT_SIZE);
    BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
    FontMetrics fm = img.getGraphics().getFontMetrics(font);
    int titleWidth = fm.stringWidth(myString);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:27:01