如何使用 Jasper 报告创建带有子表的 Excel 报告

How to create Excel report with subtable with Jasper reports

我正在使用 Jasper 报告以编程方式创建 Excel 文件。我正在使用 Java 数据源 - 实现 JRDataSource 接口的 java class。到目前为止,我的数据源返回了一个包含 class 个实例的列表,看起来像这样:

public Class MyDataSource implements JRDataSource {
  private Integer prop1;
  private String prop2;
  private String prop3;
  ...
  // getters and setters omitted to save space
}

有了这个数据源,我能够创建一个非常漂亮的 excel table 看起来:

prop1-Header prop2-Header prop3-Header...
----------------------------------------
prop1-value  prop2-value  prop3-value...
prop1-value  prop2-value  prop3-value...
...

但是现在MyDataSourceclass有额外的属性List<String>

public Class MyDataSource implements JRDataSource {
  private Integer prop1;
  private String prop2;
  private String prop3;
  private List<String> subvalues;
  ...
  // getters and setters omitted to save space
}

所以我需要我的 excel 看起来像这样

prop1-Header prop2-Header prop3-Header...
----------------------------------------
prop1-value  prop2-value  prop3-value...
                                         Sub-header1 Sub-header2...
                                         -----------------------
                                         sub-value1  sub-value2....
                                         ....
prop1-value  prop2-value  prop3-value...
                                         Sub-header1 Sub-header2...
                                         -----------------------
                                         sub-value1  sub-value2....
                                         ....
...

我设法通过将列表连接成一个字符串来做到这一点,它看起来与我需要的非常相似。但是我没有办法对子值数据进行排序和过滤。所以,我实际上需要将其作为子列表或子 table。这是我的问题 - 如何做到这一点?

经过一段时间的搜索,我找到了解决方案。首先,这是一个非常好的 youtube 视频

How to fill Jasper Report Table using Collection of data in Java?

该视频详细展示了如何将 java 代码传递到报告中,除了您的数据源 java class 之外还有一个额外的集合。这是通过做这样的事情来完成的:

    JRBeanCollectionDataSource detailBean = new JRBeanCollectionDataSource(getMySubvaluesINstancesList());
    Map<String, Object> params = new HashMap<>();
    params.put("DetailDataSource", detailBean);
    jasperPrint = JasperFillManager.fillReport(jasperReport, params, ds);


请注意名称 "DetailDataSource"。在您的报告中,您需要创建一个具有该名称的参数并将其类型声明为 net.sf.jasperreports.engine.data.JRBeanCollectionDataSource。之后,您根据根据该参数创建的数据集构建 table。但这是对上面引用的视频的简短描述。

然而,仅此还不能解决问题。集合作为参数传递的剩余问题只会呈现一次,不会为数据源的每条记录呈现。所以,我们需要做的是将我们的列表 属性 添加到我们的数据源 class 中,方法与问题中描述的相同:

public Class MyDataSource implements JRDataSource {
  private Integer prop1;
  private String prop2;
  private String prop3;
  private List<String> subvalues;
  ...
  // getters and setters omitted to save space
}


之后,在您的报告中,您需要声明一个名为 "subvalues" 的字段并将其类型声明为 java.util.List。然后根据上面引用的视频更改您创建的数据集的定义。您需要将 JRDatasource 表达式从 $P{yourParameterName} 更改为 new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{subvalues}) 并且宾果游戏!您的集合是数据源的一部分,将为每条记录呈现