Apache FOP配置resources/fonts相对路径字体仍无法识别求助
解决Apache FOP相对路径加载Arial字体失败问题
我的字体存放路径为resources/fonts/Arial.ttf,已通过以下代码引用相对路径:
FontUris fontUris = new FontUris(Thread.currentThread().getContextClassLoader() .getResource("fonts/Arial.ttf").toURI(), null); fopFactoryBuilder.getFontManager().setResourceResolver( ResourceResolverFactory.createDefaultInternalResourceResolver(fontUris.getEmbed())); confInputStream = FopGenerator.class.getClassLoader().getResourceAsStream("fopconf.xconf"); fopFactoryBuilder.setConfiguration(new DefaultConfigurationBuilder().build(confInputStream));
对应的fopconf.xconf配置:
<?xml version="1.0" encoding="utf-8" ?> <fop> <strict-validation>false</strict-validation> <base>.</base> <font-base>./</font-base> <renderers> <renderer mime="application/pdf"> <fonts> <font kerning="yes" embed-url="Arial.ttf" embedding-mode="subset"> <font-triplet name="Arial" style="normal" weight="400"/> </font> </fonts> </renderer> </renderers> </fop>
调试时确认fontUris中的嵌入URL已指向正确路径:/Users/midi/IdeaProjects/MyProject/forms/target/classes/fonts/Arial.ttf,但打印文档时仍收到警告:
org.apache.fop.apps.FOUserAgent : Font "Arial,normal,400" not found. Substituting with "any,normal,400".
解决方法:
调整配置加载与资源解析器的顺序
FOP加载配置文件时会重置FontManager的部分配置,导致提前设置的ResourceResolver失效。需先加载配置,再设置ResourceResolver:// 先加载配置 confInputStream = FopGenerator.class.getClassLoader().getResourceAsStream("fopconf.xconf"); fopFactoryBuilder.setConfiguration(new DefaultConfigurationBuilder().build(confInputStream)); // 再设置资源解析器 FontUris fontUris = new FontUris(Thread.currentThread().getContextClassLoader() .getResource("fonts/Arial.ttf").toURI(), null); fopFactoryBuilder.getFontManager().setResourceResolver( ResourceResolverFactory.createDefaultInternalResourceResolver(fontUris.getEmbed()));修正配置文件中的字体路径
由于字体位于classpath的fonts目录下,需修改font-base或直接指定完整的classpath路径:
方案1:修改font-base为classpath路径<font-base>classpath:fonts/</font-base> <font kerning="yes" embed-url="Arial.ttf" embedding-mode="subset">方案2:直接在
embed-url中指定classpath路径<font kerning="yes" embed-url="classpath:fonts/Arial.ttf" embedding-mode="subset">验证FO文件与配置的字体三元组匹配
确保FO文档中引用的字体参数和配置里的<font-triplet>完全一致:- FO中需明确指定:
font-family="Arial"、font-style="normal"、font-weight="400" - 避免拼写错误(比如Arial写成ArialMT,或大小写不匹配)
- FO中需明确指定:
备选:直接通过代码注册字体
如果配置文件方式仍有问题,可跳过配置,直接在代码中注册字体:FontManager fontManager = fopFactoryBuilder.getFontManager(); URI fontUri = Thread.currentThread().getContextClassLoader().getResource("fonts/Arial.ttf").toURI(); fontManager.addFont(fontUri, true);
内容的提问来源于stack exchange,提问作者midi
相关产品推荐
相关产品推荐

