在我的 Tomcat Web 应用程序中,我有一个 Java 文件,负责加载和编译 Jasper jrxml 文件。
JasperReport jasperReport = reportMap.get(reportName);
if (jasperReport == null) {
synchronized (reportMap) {
jasperReport = reportMap.get(reportName);
if (jasperReport == null) {
InputStream in;
if (reportName.contains("csv"))
in = getClass().getClassLoader().getResourceAsStream(
"report/" + reportName + "_CSV.jrxml");
else
in = getClass().getClassLoader().getResourceAsStream(
"report/" + reportName + ".jrxml");
JasperDesign design = JRXmlLoader.load(in);
jasperReport = JasperCompileManager.compileReport(design);
reportMap.put(reportName, jasperReport);
}
}
}
return jasperReport;
到目前为止,这一切都很好,因为我继承的报告模板没有子报告,但我现在面临的问题是我正在开发一个新的报告模板,它的要求需要使用子报告。
这些是我到目前为止已完成的步骤:
在与所有其他 jrxml 文件相同的文件夹中创建了
subreport.jrxml
文件 - 在本例中为 report
文件夹(即 report/subreport.jrxml
)
在
mainreport.jrxml
中为子报表添加了以下参数:
<parameter name="SUBREPORT_DATA" class="java.util.List" isForPrompting="false">
<parameterDescription><![CDATA[Subreport Data]]></parameterDescription>
</parameter>
<subreport>
<reportElement x="20" y="150" width="410" height="60"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{SUBREPORT_DATA})]]></dataSourceExpression>
<subreportExpression><![CDATA["subreport.jasper"]]></subreportExpression>
</subreport>
为了测试子报表是否正确显示,
subreport.jrxml
暂时都是字符串存根。
当我在我的网络应用程序中测试它时,出现以下异常:
Caused by: net.sf.jasperreports.engine.JRException: Resource not found at : subreport.jasper
at net.sf.jasperreports.repo.RepositoryUtil.getResource(RepositoryUtil.java:155) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.repo.RepositoryUtil.getReport(RepositoryUtil.java:126) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateReport(JRFillSubreport.java:317) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport(JRFillSubreport.java:347) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluate(JRFillSubreport.java:275) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:257) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:473) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillNoData(JRVerticalFiller.java:2192) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:207) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:836) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:765) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:84) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:624) ~[oss-net-sf-jasperreports-4.1.3.jar:4.1.3]
...
显然子报表表达式是错误的,但我不知道应该将其更改为什么(
report/subreport.jasper
也不起作用。) - 我快速搜索了我的文件系统,似乎没有 jasper 文件正在运行生成了?
如果事先知道主报表使用的是哪个子报表,则可以将子报表编译成JasperReport对象(使用与主报表相同的代码),将JasperReport对象作为参数传递,并在子报表中使用该参数表达。
类似这样的:
JasperReports subreport = compileReport("subreport.jrxml");
...
parameters.put("SUBREPORT", subreport);
报告中:
<parameter name="SUBREPORT" class="net.sf.jasperreports.engine.JasperReport" isForPrompting="false">
<parameterDescription><![CDATA[Subreport]]></parameterDescription>
</parameter>
...
<subreportExpression><![CDATA[$P{SUBREPORT}]]></subreportExpression>