如何将Java bean属性映射到报告部件字段?

时间:2016-04-04 21:15:11

标签: java jasper-reports subreport

我试图在我的Jasper报告中实现目录。以下是Jasper Reports网站上提供的如何执行此操作的示例:https://sourceforge.net/p/jasperreports/code/ci/jr-6-2-1/tree/jasperreports/demo/samples/tableofcontents/reports/

在上面的示例中,他们针对db运行查询以获取数据以填充报表部件*。在我的情况下,我需要使用从JavaBean获得的数据填充报表部分,但我无法找到解决方案。

我想出了如何将数据源从包装报告传递到报告部分作为参数,但我不知道如何在那里使用它,以便所有报告部分字段都映射到它。据我所知,定期(没有报告部分)会自动完成。

到目前为止我做了什么:

  1. 用于创建报告的Java代码:
  2. JasperCompileManager.compileReportToFile("TablePart.jrxml", "TablePart.jasper");
    JasperReport jasperReport = JasperCompileManager.compileReport("TableOfContentsReport.jrxml");
    JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(generateBeanList());
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), dataSource);
    JasperExportManager.exportReportToPdfFile(jasperPrint, "TableOfContentsReport.pdf");
    
    1. Java bean
    2. public class MyBean {
      
          private Integer orderId;
          private String shipName;
          private String shipCity;
          private String shipCountry;
          private Integer total;
      
          public Integer getOrderId() {
              return orderId;
          }
      
          public void setOrderID(Integer orderId) {
              this.orderId = orderId;
          }
      
          public String getShipName() {
              return shipName;
          }
      
          public void setShipName(String shipName) {
              this.shipName = shipName;
          }
      
          public String getShipCity() {
              return shipCity;
          }
      
          public void setShipCity(String shipCity) {
              this.shipCity = shipCity;
          }
      
          public String getShipCountry() {
              return shipCountry;
          }
      
          public void setShipCountry(String shipCountry) {
              this.shipCountry = shipCountry;
          }
      
          public Integer getTotal() {
              return total;
          }
      
          public void setTotal(Integer total) {
              this.total = total;
          }
      }
      
      1. 包装报告jrxml模板(稍微修改过的TableOfContentsReport.jrxml版本(上面的链接)):
      2. <jasperReport ... sectionType="Part" ...>
            <group name="dummy">
                <groupExpression><![CDATA[]]></groupExpression>
                <groupHeader>
                ...
                    <part>
                        <p:subreportPart xmlns:p="http://jasperreports.sourceforge.net/jasperreports/parts"                            xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/parts http://jasperreports.sourceforge.net/xsd/parts.xsd"
                                         usingCache="true">
                            <subreportParameter name="REPORT_DATA_SOURCE">
                                <subreportParameterExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></subreportParameterExpression>
                            </subreportParameter>
                            <subreportExpression><![CDATA["TablePart.jasper"]]></subreportExpression>
                        </p:subreportPart>
                    </part>
                </groupHeader>
            </group>
        </jasperReport>
        

        我发现可以将包装报告中的数据源作为参数传递给报表部分:$ P {REPORT_DATA_SOURCE}

        但是如何在报表部分中使用它来映射相应的字段(Jasper Reports字段到JavaBean字段)?它现在的方式是报表部分中的所有声明字段都计算为null。

        1. 报告部分(TablePart.jrxml的略微修改版本(上面的链接))
        2. <jasperReport ...>
              <queryString><![CDATA[]]></queryString>
              <field name="orderId" class="java.lang.Integer"/>
              <field name="shipName" class="java.lang.String"/>
              <field name="shipCity" class="java.lang.String"/>
              <field name="shipCountry" class="java.lang.String"/>
              ...
          </jasperReport>
          

          这些是我需要使用传递的JavaBean的相应值设置的字段(orderId,shipName等)。

          *以防万一,以下是报告部分主题的参考:http://jasperreports.sourceforge.net/sample.reference/book/index.html

1 个答案:

答案 0 :(得分:1)

问题是您传递到子报表的数据源已消耗

JRDatasource使用next来迭代主报表中的详细信息区段以及何时将其传递给子报表。

<强>解决方案:

  1. 传递给主报告new JREmptyDataSource(1),只需要1条记录

  2. 将您的数据源作为参数传递到HashMap<String,Object> es map.put("subreportDataSource",dataSource)

  3. 传递给子报告此数据源

    <subreportParameter name="REPORT_DATA_SOURCE">
       <subreportParameterExpression><![CDATA[$P{subreportDataSource}]]></subreportParameterExpression>
    </subreportParameter>
    
  4. 跟进问题

      

    是否有可能在所有报告部分之间共享一个数据源?

    不直接作为数据源,但在您的情况下,您可以将generateBeanList()作为参数map.put("dsList",generateBeanList())传递给每个子报告传递new JRBeanCollectionDataSource($P{dsList})