我有一个包含2个子报告的主报告。我正在使用自定义数据源来获取报告内容。但是,在jasper studio中预览主报表时,只会显示一个子报表(无论哪个子报表首先出现)。
例如。只显示report1.jrxml。如果删除该子报告,则会显示report2.jrxml。
main.jrxml
<detail>
<band height="250">
<subreport runToBottom="true">
<reportElement positionType="Float" x="0" y="130" width="1960" height="120" uuid="89a9f872-756e-4c82-922d-537cfde30cca"/>
<dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></dataSourceExpression>
<subreportExpression><![CDATA["report1.jrxml"]]></subreportExpression>
</subreport>
</band>
<band height="250">
<subreport runToBottom="true">
<reportElement positionType="Float" x="0" y="90" width="1960" height="120" uuid="892c0849-9532-48cb-94c0-f2e87528232a"/>
<dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></dataSourceExpression>
<subreportExpression><![CDATA["report2.jrxml"]]></subreportExpression>
</subreport>
</band>
</detail>
我尝试了以下内容:
答案 0 :(得分:3)
问题在于尝试将 相同数据源 用于多个子报表。第一个子报告的数据源已耗尽,因此后续子报告没有可用的数据。
解决方案:
您必须使用 JRRewindableDataSource
来回放数据源感谢lucianc Community answer
总结任务:
创建一个包装RewindableDSWrapper,它会倒回数据源并委托对它的所有调用。
package com.jasper.api;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;
import net.sf.jasperreports.engine.JRRewindableDataSource;
public class RewindableDSWrapper implements JRRewindableDataSource {
private final JRRewindableDataSource ds;
public RewindableDSWrapper(JRRewindableDataSource ds) {
this.ds = ds;
try {
this.ds.moveFirst();
} catch (JRException e) {
e.printStackTrace();
}
}
public boolean next() throws JRException {
return ds.next();
}
public Object getFieldValue(JRField jrField) throws JRException {
return ds.getFieldValue(jrField);
}
public void moveFirst() throws JRException {
ds.moveFirst();
}
}
在自定义数据源类中实现JRRewindableDataSource接口。
public void moveFirst() throws JRException {
// provide logic for rewinding datasource
}
在您的jrxml文件中,如果您的数据源是自定义的,那么
<dataSourceExpression><![CDATA[new com.jasper.api.RewindableDSWrapper((JRRewindableDataSource)$P{REPORT_DATA_SOURCE})]]></dataSourceExpression>
您将REPORT_DATA_SOURCE转换为JRRewindableDataSource,因为编译器会尝试将其转换为JRDataSource。
同时将包含RewindableDSWrapper类的jar文件添加到工作室的classpath中。
答案 1 :(得分:0)
我找到了不需要其他Java类的替代解决方案。如果您的数据源是JRBeanCollectionDataSource
,则可以像下面这样在dataSourceExpression字段内调用方法cloneDataSource()
:
<dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}.cloneDataSource()]]></dataSourceExpression>
这将实例化一个新的迭代器,它与moveFirst()
方法中发生的事情相同。