主报表中的多个子报表使用相同的数据源

Har*_*han 5 jasper-reports

我有一个主报告和两个子报告。我正在使用自定义数据源来获取报告内容。但在 jasper studio 中预览主报表时,仅显示一个子报表(以先出现的子报表为准)。

例如。仅显示report1.jrxml。如果我删除该子报表,则会显示report2.jrxml。

主.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>
Run Code Online (Sandbox Code Playgroud)

我已经尝试过以下方法:

  1. 将子报表放置在不同的详细信息区域中。
  2. 将“头寸类型”设置为“浮动”。
  3. 将“运行到底部”属性设置为“True”。

Har*_*han 4

问题在于尝试对多个子报表使用相同的数据源。第一个子报表的数据源已耗尽,因此后续子报表没有可用数据。

解决方案 :

您必须使用JRRewindableDataSource倒带数据源

感谢 lucianc社区的回答

总结一下任务:

创建一个包装器 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();

   }

 }
Run Code Online (Sandbox Code Playgroud)

在您的自定义数据源类中实现 JRRewindableDataSource 接口。

public void moveFirst() throws JRException {
    // provide logic for rewinding datasource
}
Run Code Online (Sandbox Code Playgroud)

在你的 jrxml 文件中,如果你的数据源是自定义的,那么

<dataSourceExpression><![CDATA[new com.jasper.api.RewindableDSWrapper((JRRewindableDataSource)$P{REPORT_DATA_SOURCE})]]></dataSourceExpression>
Run Code Online (Sandbox Code Playgroud)

您将 REPORT_DATA_SOURCE 转换为 JRRewindableDataSource,因为编译器会尝试将其转换为 JRDataSource。

还将包含 RewindableDSWrapper 类的 jar 文件添加到工作室中的类路径中。