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
相关产品推荐
相关产品推荐

