BIRT PDF呈现:字体注册时间

BIRT PDF呈现:字体注册时间,pdf,fonts,itext,render,birt,Pdf,Fonts,Itext,Render,Birt,我们从版本2(目前使用4.2.2)开始使用BIRT,并且一直受到PDF(itext?)字体注册时间的困扰 org.eclipse.birt.report.engine.layout.pdf.font.FontMappingManagerFactory$2 run INFO: register fonts in c:/windows/fonts cost:17803ms 此过程仅在第一次使用渲染时发生。后续渲染没有问题 问题似乎在于访问所有系统连接的驱动器时浪费的时间 在org.eclipse.

我们从版本2(目前使用4.2.2)开始使用BIRT,并且一直受到PDF(itext?)字体注册时间的困扰

org.eclipse.birt.report.engine.layout.pdf.font.FontMappingManagerFactory$2 run
INFO: register fonts in c:/windows/fonts cost:17803ms
此过程仅在第一次使用渲染时发生。后续渲染没有问题

问题似乎在于访问所有系统连接的驱动器时浪费的时间

在org.eclipse.birt.report.engine.fonts插件中编辑fontsConfig.xml,减少搜索路径并不能解决问题所有连接的驱动器都由BIRT访问

<font-paths>
    <path path="/windows/fonts" />
</font-paths>


是否有一个简单的解决方案,无需在后台呈现“虚拟”报告来初始化BIRT???

我建议您可以修改fontsConfig.xml并删除不再需要的字体。同时删除您不希望birt检查字体的驱动器。

这不一定是一个解决方案,但可能是我在注意到相同问题并进行了一些调查后提出的另一个解决方案。在国际海事组织(IMO)中,它也比生成虚拟报告要好

启动时(或根据需要在其他时间点),拨打以下电话:

FontMappingManagerFactory.getInstance().getFontMappingManager(format, Locale.getDefault());
为什么? BIRT使用
com.lowagie.text.FontFactory
()注册字体。对该类的调用来自 这也会吐出问题中给出的日志条目

FontMappingManagerFactory
中,我们可以看到日志条目的来源:

private static void registerFontPath( final String fontPath )
{
    AccessController.doPrivileged( new PrivilegedAction<Object>( ) {

        public Object run( )
        {
            long start = System.currentTimeMillis( );
            File file = new File( fontPath );
            if ( file.exists( ) )
            {
                if ( file.isDirectory( ) )
                {
                    FontFactory.registerDirectory( fontPath );
                }
                else
                {
                    FontFactory.register( fontPath );
                }
            }
            long end = System.currentTimeMillis( );
            logger.info( "register fonts in " + fontPath + " cost:"
                    + ( end - start ) + "ms" ); // <-- Here!
            return null;
        }
    } );
}
getFontMappingManager(字符串,区域设置)
是我们可以调用的公共方法。但是,更重要的是,该方法还缓存创建的
FontMappingManager

public synchronized FontMappingManager getFontMappingManager(
        String format, Locale locale )
{
    HashMap managers = (HashMap) cachedManagers.get( format );
    if ( managers == null )
    {
        managers = new HashMap( );
        cachedManagers.put( format, managers );
    }
    FontMappingManager manager = (FontMappingManager) managers.get( locale );
    if ( manager == null )
    {
        manager = createFontMappingManager( format, locale );
        managers.put( locale, manager );
    }
    return manager;
}
因此,当您准备好生成PDF时,它已经在缓存中,BIRT不必调用FontFactory并重新注册字体

但是格式字符串呢? 这是一些推测,但我认为有效的选项是
IRenderOption
中的
OUTPUT\u FORMAT\u XXX
String
s。出于我们的目的,我调试了
字符串
pdf
。考虑到这也是所需的输出格式,我假设
IRenderOption.output\u format\u PDF
是一条可行的途径

如果您最终同时创建PDF和HTML文件,那么似乎可以调用两次(一次使用
IRenderOption.OUTPUT\u FORMAT\u PDF
,一次使用
IRenderOption.OUTPUT\u FORMAT\u HTML
),并且只考虑不同的字体配置文件(即,您将不会从
c:/windows/font
阅读两次)



我相信这是完全安全的,因为
getFontMappingManager(字符串,区域设置)的目的是
是获取一个对象,用于访问可用字体等,它可以方便地缓存结果。但是,如果这种情况在将来发生变化,您可能会发现手上有一个棘手的bug。

这个问题有什么好运气吗?在我的情况下,需要53秒!是的。我每天都测试BIRT,我注意到一些用户没有这个问题,即使是在相同的S.O上。(与Linux/MAC/Windows的差异是意料之中的!)。时间与系统中的驱动器数量成正比,即使您在org.eclipse.birt.report.engine.fonts插件上配置了fontsConfig.xml。在只有一个驱动器连接的系统中尝试birt,并给出您的反馈。非常有趣!我有15个驱动器(包括网络共享)。可能是时候放弃其中一些了!我会找一个驱动器更少的大学来测试预热时间,然后我会回复你。15个驱动器当然可以解释52秒!(当我的6个外部驱动器都打开时,我会得到20到23秒…)我已将连接的驱动器数减少到9,这样更好。这与您提到的时间相对应。我的同事声称他的启动时间非常短(2-3)秒,但我无法验证。我已将初始化放在“预热”线程中,以便Birt在实际需要之前启动。正如我在问题上所说:编辑org.eclipse.Birt.report.engine.fonts插件中的fontsConfig.xml,减少搜索路径并不能解决问题。所有连接的驱动器都由BIRT.impeccable!!效果很好!而且解释得很好(应该如此!)。我只是不明白“区域设置”的必要性:\n我使用默认的区域设置,但我想知道BIRT从哪里获取区域设置来访问FontMappingManager
public synchronized FontMappingManager getFontMappingManager(
        String format, Locale locale )
{
    HashMap managers = (HashMap) cachedManagers.get( format );
    if ( managers == null )
    {
        managers = new HashMap( );
        cachedManagers.put( format, managers );
    }
    FontMappingManager manager = (FontMappingManager) managers.get( locale );
    if ( manager == null )
    {
        manager = createFontMappingManager( format, locale );
        managers.put( locale, manager );
    }
    return manager;
}