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

XSLT-1.0中SVG文本水印引发InvocationTargetException问题求助

问题:SVG水印在FOP渲染PDF时抛出字体相关错误

我尝试用SVG文本作为PDF水印,对应的XSLT模板代码如下:

<xsl:template name="Draft">
 <fo:block-container z-index="-1" position="absolute" right="-20mm">
  <fo:block>
   <fo:instream-foreign-object>
    <svg:svg xmlns:svg="http://www.w3.org/2000/svg" height="157mm" width="190mm">
     <svg:text x="140" y="520" transform="rotate(-46.5,50,350)" textLength="125mm" font-style="fill:rgb(0,0,0);fill-opacity:0.3" font-size="50mm" lengthAdjust="spacingAndGlyphs">
      DRAFT
     </svg:text>
    </svg:svg>
   </fo:instream-foreign-object>
  </fo:block>
</fo:block-container>
</xsl:template>

执行时出现如下错误:

Exception in thread "main" java.lang.InternalError: java.lang.reflect.InvocationTargetException
        at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:87)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
        at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:75)
        at java.desktop/sun.java2d.SunGraphicsEnvironment.getFontManagerForSGE(SunGraphicsEnvironment.java:139)
        at java.desktop/sun.java2d.SunGraphicsEnvironment.getAvailableFontFamilyNames(SunGraphicsEnvironment.java:173)
        at java.desktop/sun.java2d.SunGraphicsEnvironment.getAvailableFontFamilyNames(SunGraphicsEnvironment.java:201)
        at java.desktop/sun.java2d.HeadlessGraphicsEnvironment.getAvailableFontFamilyNames(HeadlessGraphicsEnvironment.java:80)
        at org.apache.batik.bridge.DefaultFontFamilyResolver.<clinit>(DefaultFontFamilyResolver.java:86)
        at org.apache.fop.image.loader.batik.PreloaderSVG$Loader.createImageInfo(PreloaderSVG.java:165)
        at org.apache.fop.image.loader.batik.PreloaderSVG$Loader.getImage(PreloaderSVG.java:131)
        at org.apache.fop.image.loader.batik.PreloaderSVG$Loader.access$200(PreloaderSVG.java:108)
        at org.apache.fop.image.loader.batik.PreloaderSVG.preloadImage(PreloaderSVG.java:76)
        at org.apache.xmlgraphics.image.loader.ImageManager.preloadImage(ImageManager.java:176)
        at org.apache.fop.render.intermediate.AbstractIFPainter.drawImageUsingDocument(AbstractIFPainter.java:323)
        at org.apache.fop.render.pdf.PDFPainter.drawImage(PDFPainter.java:290)
        at org.apache.fop.render.intermediate.IFRenderer.renderForeignObject(IFRenderer.java:1324)
        at org.apache.fop.render.AbstractRenderer.renderInlineViewport(AbstractRenderer.java:1034)
        at org.apache.fop.render.AbstractPathOrientedRenderer.renderInlineViewport(AbstractPathOrientedRenderer.java:836)
        at org.apache.fop.render.intermediate.IFRenderer.renderInlineViewport(IFRenderer.java:860)
        at org.apache.fop.render.AbstractRenderer.renderInlineArea(AbstractRenderer.java:877)
        at org.apache.fop.render.intermediate.IFRenderer.renderInlineArea(IFRenderer.java:924)
        at org.apache.fop.render.AbstractRenderer.renderLineArea(AbstractRenderer.java:845)
        at org.apache.fop.render.AbstractRenderer.renderBlocks(AbstractRenderer.java:704)
        at org.apache.fop.render.AbstractRenderer.renderBlock(AbstractRenderer.java:758)
        at org.apache.fop.render.intermediate.IFRenderer.renderBlock(IFRenderer.java:1004)
        at org.apache.fop.render.AbstractRenderer.renderBlocks(AbstractRenderer.java:689)
        at org.apache.fop.render.AbstractPathOrientedRenderer.renderReferenceArea(AbstractPathOrientedRenderer.java:759)
        at org.apache.fop.render.AbstractRenderer.renderBlock(AbstractRenderer.java:744)
        at org.apache.fop.render.intermediate.IFRenderer.renderBlock(IFRenderer.java:1004)
        at org.apache.fop.render.AbstractRenderer.renderBlocks(AbstractRenderer.java:689)
        at org.apache.fop.render.intermediate.IFRenderer.renderBlockViewport(IFRenderer.java:809)
        at org.apache.fop.render.AbstractRenderer.renderBlock(AbstractRenderer.java:737)
        at org.apache.fop.render.intermediate.IFRenderer.renderBlock(IFRenderer.java:1004)
        at org.apache.fop.render.AbstractRenderer.renderBlocks(AbstractRenderer.java:689)
        at org.apache.fop.render.AbstractRenderer.renderRegion(AbstractRenderer.java:418)
        at org.apache.fop.render.AbstractRenderer.renderRegionViewport(AbstractRenderer.java:38

相关注意事项:

  • 移除水印后PDF可正常渲染
  • 其他未指定font-family的元素可自动转为UTF-8编码渲染

服务器日志对比

服务器1(水印渲染成功)

[WARN] FOUserAgent - Font "Symbol,normal,700" not found. Substituting with "Symbol,normal,400".
[WARN] FOUserAgent - Font "ZapfDingbats,normal,700" not found. Substituting with "ZapfDingbats,normal,400".
[WARN] FOUserAgent - Font "Arial,normal,400" not found. Substituting with "any,normal,400".
[INFO] FOUserAgent - Rendered page #1.
[INFO] FOUserAgent - Rendered page #2.
[INFO] FOUserAgent - Rendered page #3.

服务器2(添加水印失败)

Jul 25, 2023 1:15:13 PM org.apache.fop.events.LoggingEventListener processEvent
WARNING: Font "Symbol,normal,700" not found. Substituting with "Symbol,normal,400".
Jul 25, 2023 1:15:13 PM org.apache.fop.events.LoggingEventListener processEvent
WARNING: Font "ZapfDingbats,normal,700" not found. Substituting with "ZapfDingbats,normal,400".
Exception in thread "main" java.lang.InternalError: java.lang.reflect.InvocationTargetException
        at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:87)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
        at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:75)
        at java.desktop/sun.java2d.SunGraphicsEnvironment.getFontManagerForSGE(SunGraphicsEnvironment.java:139)
        at java.desktop/sun.java2d.SunGraphicsEnvironment.getAvailableFontFamilyNames(SunGraphicsEnvironment.java:173)
        at java.desktop/sun.java2d.SunGraphicsEnvironment.getAvailableFontFamilyNames(SunGraphicsEnvironment.java:201)
        at java.desktop/sun.java2d.HeadlessGraphicsEnvironment.getAvailableFontFamilyNames(HeadlessGraphicsEnvironment.java:80)
        at org.apache.batik.bridge.DefaultFontFamilyResolver.<clinit>(DefaultFontFamilyResolver.java:86)
        at org.apache.fop.image.loader.batik.PreloaderSVG$Loader.createImageInfo(PreloaderSVG.java:165)
        at org.apache.fop.image.loader.batik.PreloaderSVG$Loader.getImage(PreloaderSVG.java:131)
        at org.apache.fop.image.loader.batik.PreloaderSVG$Loader.access$200(PreloaderSVG.java:108)
        at org.apache.fop.image.loader.batik.PreloaderSVG.preloadImage(PreloaderSVG.java:76)
        at org.apache.xmlgraphics.image.loader.ImageManager.preloadImage(ImageManager.java:176)
        at org.apache.fop.render.intermediate.AbstractIFPainter.drawImageUsingDocument(AbstractIFPainter.java:323)
        at org.apache.fop.render.pdf.PDFPainter.drawImage(PDFPainter.java:290)
        at org.apache.fop.render.intermediate.IFRenderer.renderForeignObject(IFRenderer.java:1324)
        at org.apache.fop.render.AbstractRenderer.renderInlineViewport(AbstractRenderer.java:1034)
        at org.apache.fop.render.AbstractPathOrientedRenderer.renderInlineViewport(AbstractPathOrientedRenderer.java:836)
        at org.apache.fop.render.intermediate.IFRenderer.renderInlineViewport(IFRenderer.java:860)
        at org.apache.fop.render.AbstractRenderer.renderInlineArea(AbstractRenderer.java:877)
        at org.apache.fop.render.intermediate.IFRenderer.renderInlineArea(IFRenderer.java:924)
        at org.apache.fop.render.AbstractRenderer.renderLineArea(AbstractRenderer.java:845)
        at org.apache.fop.render.AbstractRenderer.renderBlocks(AbstractRenderer.java:704)
        at org.apache.fop.render.AbstractRenderer.renderBlock(AbstractRenderer.java:758)
        at org.apache.fop.render.intermediate.IFRenderer.renderBlock(IFRenderer.java:1004)
        at org.apache.fop.render.AbstractRenderer.renderBlocks(AbstractRenderer.java:689)
        at org.apache.fop.render.AbstractPathOrientedRenderer.renderReferenceArea(AbstractPathOrientedRenderer.java:759)
        at org.apache.fop.render.AbstractRenderer.renderBlock(AbstractRenderer.java:744)
        at org.apache.fop.render.intermediate.IFRenderer.renderBlock(IFRenderer.java:1004)
        at org.apache.fop.render.AbstractRenderer.renderBlocks(AbstractRenderer.java:689)
        at org.apache.fop.render.intermediate.IFRenderer.renderBlockViewport(IFRenderer.java:809)
        at org.apache.fop.render.AbstractRenderer.renderBlock(AbstractRenderer.java:737)
        at org.apache.fop.render.intermediate.IFRenderer.renderBlock(IFRenderer.java:1004)
        at org.apache.fop.render.AbstractRenderer.renderBlocks(AbstractRenderer.java:689)
        at org.apache.fop.render.AbstractRenderer.renderRegion(AbstractRenderer.java:418)
        at org.apache.fop.render.AbstractRenderer.renderRegionViewport(AbstractRenderer.java:38

服务器2(移除水印后正常)

Jul 25, 2023 1:15:13 PM org.apache.fop.events.LoggingEventListener processEvent
WARNING: Font "Symbol,normal,700" not found. Substituting with "Symbol,normal,400".
Jul 25, 2023 1:15:13 PM org.apache.fop.events.LoggingEventListener processEvent
WARNING: Font "ZapfDingbats,normal,700" not found. Substituting with "ZapfDingbats,normal,400".
INFO: Rendered page #1.
INFO: Rendered page #2.
INFO: Rendered page #3
解决方案

1. 修复SVG文本的属性错误

原SVG代码中错误地将填充样式写在font-style属性里,这不符合SVG规范,同时未明确指定字体族。修改后的代码如下:

<xsl:template name="Draft">
 <fo:block-container z-index="-1" position="absolute" right="-20mm">
  <fo:block>
   <fo:instream-foreign-object>
    <svg:svg xmlns:svg="http://www.w3.org/2000/svg" height="157mm" width="190mm">
     <svg:text x="140" y="520" transform="rotate(-46.5,50,350)" textLength="125mm" 
               font-family="Arial, sans-serif" font-size="50mm" lengthAdjust="spacingAndGlyphs"
               fill="rgb(0,0,0)" fill-opacity="0.3">
      DRAFT
     </svg:text>
    </svg:svg>
   </fo:instream-foreign-object>
  </fo:block>
 </fo:block-container>
</xsl:template>

2. 修复服务器2的字体环境问题

错误栈显示Batik在Headless环境下获取系统字体失败,可通过以下方式解决:

  • 安装基础字体包,比如fontconfig、dejavu-fonts,提供通用 fallback 字体
  • 启动Java程序时添加Headless参数:java -Djava.awt.headless=true ...
  • 在FOP配置文件fop.xconf中明确指定字体映射,避免依赖系统自动检测:
    <fonts>
      <font kerning="yes" embed-url="file:///path/to/arial.ttf">
        <font-triplet name="Arial" style="normal" weight="normal"/>
      </font>
      <font kerning="yes" embed-url="file:///path/to/arialbd.ttf">
        <font-triplet name="Arial" style="normal" weight="bold"/>
      </font>
    </fonts>
    

3. 替换为纯FO实现(可选)

如果SVG字体问题难以解决,可直接用FO文本块实现水印,无需依赖Batik:

<xsl:template name="Draft">
 <fo:block-container z-index="-1" position="absolute" 
                     left="0" top="0" width="100%" height="100%" 
                     text-align="center">
  <fo:block font-family="Arial, sans-serif" font-size="50mm" 
            color="black" opacity="0.3" 
            writing-mode="rl" rotation="45">
    DRAFT
  </fo:block>
 </fo:block-container>
</xsl:template>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:54:54