2012-02-14 44 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。