2012-04-04 133 views
8

我有一个独立的应用程序,其职责之一是采取* .jrxml文件的路径并编译它。贾斯珀报告:如何编译子报告

我可以做到这一点没有问题,直到带有子报表的报表出现,其中主编译器没有编译它的任何子元素,导致子报表* .jasper文件在跟踪后面找不到。

有什么办法来设置JasperCompileManager自动拿起子报表

1)?

2)获取包含在JasperDesign或JasperReport对象中的子报表的路径列表?

我没有直接访问jrxml文件,因此修改报告以适应编译方法不是一种选择,也不是应用任何标准命名方案来推断哪些子报告属于哪些报告。

有一个类似的问题在这里:

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

其中JRVisitor用于生产JRSubreport对象的列表,但是没有如何使用它来获取子报表的路径解释为了编译它并递归地查找子报表的子报表,我无法弄清楚。

+0

我也想听到答案。我最终直接链接到子报表的* .jasper文件,而不是直接编译它。 :( – 2012-04-04 06:17:07

+0

类似的问题解决,而不保存在磁盘上的文件:http://stackoverflow.com/questions/9785451/generate-jasper-report-with-subreport-from-java – 2016-04-21 12:38:25

回答

8

好了,所以它需要一点两轮牛车的,但我能想办法的......

的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文件相同的位置的磁盘上,但这并不难改变。编译后的主要报告对象会在您想要运行它或任何其他内容时传回。

请记住,此代码在编辑时已有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; 
} 
+0

'compileReport()'做什么?汇编子报表存储在磁盘上? – dzieciou 2013-01-09 11:32:08

+0

@dzieciou查看上面编辑的答案 – Numeron 2013-01-10 01:35:10

+0

我知道它已经有大约2年了,但是这个答案对我来说就像魅力一样。 – 2015-06-18 18:02:42