簡體   English   中英

Jasper Reports:如何編譯子報表

[英]Jasper Reports: How to compile subreports

我有一個獨立的應用程序,它的職責之一是獲取 *.jrxml 文件的路徑並編譯它。

在出現帶有子報表的報表之前,我可以毫無問題地執行此操作,其中主報表的編譯不編譯其任何子報表,導致以后找不到子報表 *.jasper 文件。

有什么辦法

1) 將 JasperCompileManager 設置為自動獲取子報表?

2) 獲取 JasperDesign 或 JasperReport object 中包含的子報表的路徑列表?

我無法直接訪問 jrxml 文件,因此修改報告以適應編譯方法不是一種選擇,也不是應用任何標准命名方案來推斷哪些子報告屬於哪些報告。

這里有一個類似的問題:

http://jasperforge.org/plugins/espforum/view.php?group_id=102&forumid=103&topicid=40683

其中 JRVisitor 用於生成 JRSubreport 對象列表,但是沒有解釋如何使用它來獲取子報表的路徑以便編譯它並遞歸查找子報表的子報表,我無法弄清楚。

好的,所以它需要一點技巧,但我能夠想出一些辦法......

subreport.getExpression().getText() 返回主報表中子報表小部件的表達式字段,是一個看起來像這樣的字符串

$P{SUBREPORT_DIR} + "/report_sub1.jasper"

所以我能夠使用以下內容將它拆開以獲取名稱。 它不理想,但它應該堅持下去。

JRElementsVisitor.visitReport(jasperReport, new JRVisitor(){

  // ** snip other overrides **

  @Override
  public void visitSubreport(JRSubreport subreport){
    String expression = subreport.getExpression().getText().replace(".jasper", ".jrxml");
    StringTokenizer st = new StringTokenizer(expression, "\"/");
    String subreportName = null;
    while(st.hasMoreTokens())
      subreportName = st.nextToken();
    compileReport(subreportName);
  }
}

編輯:

這是我的整個 compileReport 方法,演示了如何遞歸編譯子報表等的子報表。不完美,但對我的應用程序來說已經足夠好了。 所有已編譯的 *.jasper 文件都保存回磁盤上與未編譯的 *.jrxml 文件相同的位置,但這並不難更改。 編譯后的主報告 object 會被傳回,以防您想運行它或其他任何東西。

請記住,此代碼在進行此編輯時已有 9 個月的歷史,較新版本的 Jasper Reports 現在可能具有針對此類內容的內置函數。

private static final String reportsPath = "someplace/nice/";
private ArrayList<String>   completedSubReports = new ArrayList<String>(30);
private Throwable           subReportException  = null;

/**
 * Recursively compile report and subreports
 */
public JasperReport compileReport(String reportName) throws Throwable{
  JasperDesign jasperDesign = JRXmlLoader.load(reportsPath + reportName + ".jrxml");
  JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
  JRSaver.saveObject(jasperReport, reportsPath + reportName + ".jasper");
  toLog("Saving compiled report to: " + reportsPath + reportName + ".jasper");
  //Compile sub reports
  JRElementsVisitor.visitReport(jasperReport, new JRVisitor(){
    @Override
    public void visitBreak(JRBreak breakElement){}

    @Override
    public void visitChart(JRChart chart){}

    @Override
    public void visitCrosstab(JRCrosstab crosstab){}

    @Override
    public void visitElementGroup(JRElementGroup elementGroup){}

    @Override
    public void visitEllipse(JREllipse ellipse){}

    @Override
    public void visitFrame(JRFrame frame){}

    @Override
    public void visitImage(JRImage image){}

    @Override
    public void visitLine(JRLine line){}

    @Override
    public void visitRectangle(JRRectangle rectangle){}

    @Override
    public void visitStaticText(JRStaticText staticText){}

    @Override
    public void visitSubreport(JRSubreport subreport){
      try{
        String expression = subreport.getExpression().getText().replace(".jasper", "");
        StringTokenizer st = new StringTokenizer(expression, "\"/");
        String subReportName = null;
        while(st.hasMoreTokens())
          subReportName = st.nextToken();
        //Sometimes the same subreport can be used multiple times, but
        //there is no need to compile multiple times
        if(completedSubReports.contains(subReportName)) return;
        completedSubReports.add(subReportName);
        compileReport(subReportName);
      }
      catch(Throwable e){
        subReportException = e;
      }
    }
    @Override
    public void visitTextField(JRTextField textField){}

    @Override
    public void visitComponentElement(JRComponentElement componentElement){}

    @Override
    public void visitGenericElement(JRGenericElement element){}
  });
  if(subReportException != null) throw new RuntimeException(subReportException);
  return jasperReport;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM