2012-02-14 95 views
0

我使用JasperReports和Spring MVC在我的应用程序中进行报告。 基本上我首先在iReport 4.1.1中设计报告,然后通过jasper-view.xml将结果.jasper文件放在我的课程路径中。JasperReports:Sub Report Rendering

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

这个场景是在我的主要报告中有大约15个子报表。 出于所有这些报道,只报告(“当打印”乐队的选择通过控制)

我的问题是符合标准(作为参数传递)的打印:如果我的报告是不要打印它会得到执行(即内部查询)? 还是简单地跳过?

我之所以提出这个问题,是因为报告生成需要相当长的时间(大约2秒,这对我的应用来说太长了,根据我来说)。

谢谢。

回答

4

如果您查看“Jasper Reports”的源代码,则逻辑表示首先评估'printWhenExpression',然后填充报告元素(如果要打印)。

下面是一个从称为“fillNoData” JRVerticalFiller.java(版本4.0)方法,它是这样说的:

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延续的支持 作为线程的替代方法。这是使用Jakarta Commons Javaflow库完成的。 JasperReports的属性:

  • net.sf.jasperreports.engine.fill.JRContinuationSubreportRunnerFactory
  • net.sf.: net.sf.jasperreports.subreport.runner.factory可以用 以下两个设置使用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 文件说明了如何在实际的 实现中设置此属性。用于处理 中不同查询的其他替代方法是使用List元素和Sub Datasets。