JasperReports:子报告渲染

时间:2012-02-14 13:12:10

标签: jasper-reports ireport

我在我的应用程序中使用带有Spring MVC的JasperReports进行报告。 基本上我首先在iReport 4.1.1中设计报表,然后通过jasper-view.xml将生成的.jasper文件放在我的类路径中

当请求到来时,控制器将所需的参数从Session放到参数图中并生成报告。

情况是我的主报告中有大约15个子报告。 在所有这些报告中,仅打印符合条件(作为参数传递)的报告(通过 “打印时间” 选项进行控制)

我的问题是:如果我的报告不打印它是否会被执行(即其中的查询)? 还是简单地跳过了?

我提出这个问题的理由是报告生成需要相当长的时间(大约2秒,根据我的说法,对我的申请来说太长了。)

感谢。

1 个答案:

答案 0 :(得分:5)

如果你看一下'Jasper Reports'的源代码,逻辑说首先评估'printWhenExpression',然后填写报表元素,如果要打印它。

以下是 JRVerticalFiller.java (版本4.0)中名为“ fillNoData ”的方法,其表示如下:

private void fillNoData() throws JRException
    {
        if (log.isDebugEnabled() && !noData.isEmpty())
        {
            log.debug("Fill " + fillerId + ": noData");
        }

        noData.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);

        if (noData.isToPrint())
        {
            while (noData.getBreakHeight() > pageHeight - bottomMargin - offsetY)
            {
                addPage(false);
            }

            noData.evaluate(JRExpression.EVALUATION_DEFAULT);

            JRPrintBand printBand = noData.fill(pageHeight - bottomMargin - offsetY);

            if (noData.willOverflow() && noData.isSplitPrevented() && isSubreport())
            {
                resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
                resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
                resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
                scriptlet.callBeforePageInit();
                calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
                scriptlet.callAfterPageInit();

                addPage(false);

                printBand = noData.refill(pageHeight - bottomMargin - offsetY);
            }

            fillBand(printBand);
            offsetY += printBand.getHeight();

            while (noData.willOverflow())
            {
                resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
                resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
                resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
                scriptlet.callBeforePageInit();
                calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
                scriptlet.callAfterPageInit();

                addPage(false);

                printBand = noData.fill(pageHeight - bottomMargin - offsetY);

                fillBand(printBand);
                offsetY += printBand.getHeight();
            }

            resolveBandBoundElements(noData, JRExpression.EVALUATION_DEFAULT);
        }
    }

您需要了解的是,子报表的使用如何影响性能和内存使用情况。看起来您在主报表中嵌入了太多子报表。以下是JasperForge link的内容:

Subreports是否存在性能问题?

  

答案取决于您的系统,数据源和报告   设计。关于子报告的几点注意事项:

     
      
  • 每个子报告执行可能会产生一个新线程(见下文)。
  •   
  • 当子报表执行时,将在堆内存中创建更多对象。
  •   
     

关于线程的主题。已经支持Java延续   添加作为线程的替代。这是使用雅加达完成的   Commons Javaflow图书馆。 JasperReports酒店:   net.sf.jasperreports.subreport.runner.factory可以与。一起使用   遵循两个设置:

     
      
  • net.sf.jasperreports.engine.fill.JRContinuationSubreportRunnerFactory
  •   
  • net.sf.jasperreports.engine.fill.JRThreadSubreportRunnerFactory
  •   
     

默认情况下   net.sf.jasperreports.engine.fill.JRThreadSubreportRunnerFactory是   但是如果使用的话   net.sf.jasperreports.engine.fill.JRContinuationSubreportRunnerFactory   设置好后,将使用Javaflow方法填充报告   而不是线程。如果选择此选项,则雅加达   Commons Javaflow jar必须包含在应用程序类路径中。   这个jar可以在JasperReport报告的lib目录中找到   项目分发包。 jasperreports-javaflow.properties   file说明了如何在实际中设置此属性   实现。用于处理不同查询的其他替代方法   同一报告是List元素和子数据集的使用。