在使用 Jaspersoft Report 時,除了直接在 jrxml 檔中設定 SQL 語法去 Database
查資料以外,
也可以在 Java 程式中先去 Database
中查資料,查好後再把資料送去給 Jaspersoft 產生報表。
在每個子報表 (Sub Report) 的資料來源需求都是同一個查詢,頂多 SQL Where
條件不一樣時,
這種方式可以只要用 Java 端查詢一次資料送給各子報表,
各個子報表再使用
Filter 功能去實現自己的 Where 條件篩選,
就可以避免每個子報表都要進行一次
SQL 查詢而影響效能。
以下紀錄一下使用範例。
在 Java 中:
//自己想辦法查出資料成一個 List 物件 List dataset = getDataset(); //把 List 放進 reportParams Map 中 Map reportParams = new HashMap(); reportParams.put("dataset", dataset); //把 reportParams Map 當參數送進 Jaspersoft Report 中 //然後子報表 (Sub Report) 可以把 Dataset 包裝成 Datasource 使用 JasperReport jasperReport = JasperCompileManager.compileReport("myReport.jrxml")); //Dataset 也可以作為 Data source 送給主報表 (Main Report)使用 JRDataSource dataSource = new JRMapCollectionDataSource(dataset); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, reportParams, dataSource);
在 Main Report 的 jrxml 檔中:
<!--設定名為 dataset 的 parameter 跟 Java 傳進來的 dataset 參數作對應 --> <parameter name="dataset" class="java.util.Collection"/> <!-- 用 JRMapCollectionDataSource 把 $P{dataset} 包裝成一個新的 DataSource 傳給 Sub Report --> <!-- 不把 Main Report 的 DataSource 直接傳給 Sub Report 是因為 DataSource 被讀取 (Consume) 後就不能再讀了, --> <!-- 會造成 Sub Report 把 Main Report 的 DataSource 吃掉讓 Main Report 讀不到資料。 --> <subreport> ........... <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRMapCollectionDataSource($P{dataset})]]></dataSourceExpression> ............ </subreport>
在 Sub Report 的 jrxml 檔中:
<!-- 在 Sub Report 中可以用 <filterExpression> 的功能過濾篩選資料,實現像 SQL Where 的效果 --> <!-- 例如下面範例: --> <!-- 從 Main Report 得到的 DataSource 取得的 Dataset 中, --> <!-- 有名為 groupName 的 String 欄位 (field), 設定 field 去接收它,例如值可能有 1, 2, 3, 或 4 --> <field name="groupName" class="java.lang.String"/> <!-- 設定 parameter 去接收 Main Report 傳給 Sub Report 的另一個名為 groupNameForFilter 的參數,例如值為 3 代表想篩選出只是 3 的 DataSet --> <parameter name="groupNameForFilter" class="java.lang.String"/> <!-- 用 filterExpression 功能去設定篩選條件為:$F{groupName} 要等於 $P{groupNameForFilter} --> <filterExpression><![CDATA[$F{groupName}.equals($P{groupNameForFilter})]]></filterExpression>