iT邦幫忙

2024 iThome 鐵人賽

DAY 5
0
Software Development

Java工程師的報表入門與實作系列 第 5

JasperReports-用Java匯出Excel範例報表

  • 分享至 

  • xImage
  •  

上一篇我們用Jaspersoft Studio設計好報表模板後,要如何用Java後端處理資料並且匯出Excel呢?

Maven

第一件事還是要先把JasperReports的dependency放好!
Maven dependency - Jasperreports

<dependency>
    <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports</artifactId>
    <version>6.20.0</version>
</dependency>

DataSource

一般來說,我們的資料來源常常是SQL查詢結果,但這是簡單的Demo,就先自己新增一些模擬數據。不過要把握以下原則:類別屬性的名稱與型別都要與Fields相同

  1. 查看目前有哪些Fields
Fields 型別
productName String
productPrice Integer
productNum Integer
priceSum Integer
  1. 建立Java類別,屬性的名稱與型別與Fields相同
import lombok.Data;

@Data
public class BBQSuppliesModel {
    // 商品名稱
    private String productName;

    // 商品金額
    private Integer productPrice;

    // 商品數量
    private Integer productNum;

    // 購買金額小記
    private Integer priceSum;

    // 用Constructor方便創建物件以及計算購買金額小記
    public BBQSuppliesModel(String productName, Integer productPrice, Integer productNum) {
        this.productName = productName;
        this.productPrice = productPrice;
        this.productNum = productNum;
        // 購買金額小記由 商品金額 * 商品數量 計算而來
        this.priceSum = productPrice * productNum;
    }
}
  1. 新增一些模擬資料
// 建立Demo資料
List<BBQSuppliesModel> bbqSuppliesModelList = new ArrayList<>();
BBQSuppliesModel bbqSuppliesModel1 = new BBQSuppliesModel("烤肉醬刷", 20, 3);
BBQSuppliesModel bbqSuppliesModel2 = new BBQSuppliesModel("烤肉醬", 200, 2);
BBQSuppliesModel bbqSuppliesModel3 = new BBQSuppliesModel("豬里肌", 150, 2);
BBQSuppliesModel bbqSuppliesModel4 = new BBQSuppliesModel("雪花牛", 250, 1);
BBQSuppliesModel bbqSuppliesModel5 = new BBQSuppliesModel("香菇", 120, 2);
bbqSuppliesModelList.add(bbqSuppliesModel1);
bbqSuppliesModelList.add(bbqSuppliesModel2);
bbqSuppliesModelList.add(bbqSuppliesModel3);
bbqSuppliesModelList.add(bbqSuppliesModel4);
bbqSuppliesModelList.add(bbqSuppliesModel5);

Parameters

除了Fields,別忘了還有Parameters,一樣Java中型別需要與Parameters相同

  1. 查看目前有哪些Parameters
Parameters 型別
formatDate String
totalAmount Integer
  1. REPORT_PARAMETERS_MAP

    • 在JasperReports中參數的傳遞與取得都是靠REPORT_PARAMETERS_MAP,由下圖可看到這是一個預設的報表參數,由JasperReports自動管理
    • REPORT_PARAMETERS_MAP的型別為Map<String, Object>,傳遞參數時將Parameters名稱作為key,數值物件作為value放入REPORT_PARAMETERS_MAP中
  2. 我們分別設定兩個Parameters,並放入REPORT_PARAMETERS_MAP中

// 設定報表參數,建立REPORT_PARAMETERS_MAP
Map<String, Object> parametersMap = new HashMap<>();

// 第一個parameter:購買日期
LocalDate localDate = new Date().toInstant()
                        .atZone(ZoneId.systemDefault()).toLocalDate();
// 格式化購買日期 yyyy-MM-dd
String formatDate = localDate
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
parametersMap.put("formatDate", formatDate);

// 第二個parameter:計算金額總計
Integer totalAmount = bbqSuppliesModelList.stream()
                        .mapToInt(BBQSuppliesModel::getPriceSum).sum();
parametersMap.put("totalAmount", totalAmount);

匯出Excel

Java後端的部分能夠由JasperReports API輕鬆將DataSource放入報表模板,並編譯報表。

  1. 取得報表模板路徑,我放在Resources底下,因此路徑為
    String reportPath = "/Report/Jasper/demo.jrxml";

  2. 報表生命週期:在JasperReports 簡介曾提到報表的生命週期,我們目前只完成了「報表設計」,後面三步都能靠Java完成

    • JasperCompileManager:將jrxml模板編譯成jasper文件(.jasper
    • JRDataSource:是一個interface,定義了從數據源中提取數據的操作
    • JRBeanCollectionDataSource:是JRDataSource的一個實現,用於處理Java Bean的數據,封裝成報表DataSource,每個Bean對應報表Detail中的一列,Bean的屬性對應報表中的Fields
    • JasperFillManager:將報表模板(.jasper文件)和DataSource結合,回傳JasperPrint,包含了報表的所有資料和格式化結果
    • JRXlsxExporter:用於匯出Excel格式(XLSX)報表的工具,將JasperPrint生成的報表結果匯出為Excel文件
// 匯出excel byte[]
String reportPath = "/Report/Jasper/demo.jrxml";
byte[] bytes = null;
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
    // 以JasperCompileManager將jrxml模板編譯成jasper文件
    JasperReport jasperReport = JasperCompileManager
    // 我的方法放在JasperDemoFacadeImpl中
    .compileReport(JasperDemoFacadeImpl.class.getResourceAsStream(reportPath));

    // 將Java集合資料來源與Jasper報表進行綁定
    JRDataSource dataSource = new JRBeanCollectionDataSource(bbqSuppliesModelList);

    // 將資料填入報表
    JasperPrint print = JasperFillManager
    .fillReport(jasperReport, parametersMap, dataSource);

    // 匯出XLSX
    JRXlsxExporter exporter = new JRXlsxExporter();
    exporter.setExporterInput(new SimpleExporterInput(print));
    exporter
        .setExporterOutput(new SimpleOutputStreamExporterOutput(byteArrayOutputStream));
    exporter.exportReport();

    bytes = byteArrayOutputStream.toByteArray();
} catch (Exception e) {
    throw new RuntimeException(e);
}
  1. 大致上到這邊已經幾乎完成了,後續只要處理檔案名稱和byte []就能下載Excel囉
    • 可以檢查物件BBQSuppliesModel的資料與Parameters的資料是否都正確填入報表
    • Detail Band的列數會根據List<BBQSuppliesModel>有多少資料而增長
    • 報表設計好朋友Jaspersoft Studio(上)-建立空白模板、認識使用介面有提到Title是只會在第一頁顯示,Page Header與Column Header會在每一頁重複顯示,可以由下圖應證
    • 而一頁的大小是在「Edit Page format」中設定,因為我設定高度為150px,一頁才這麼短

調整為不分頁

分頁功能通常是在pdf或word才需要的,以這個範例來說不適合,我們可以透過勾選「ignore pagination」告訴JasperReports這個報表不要分頁,再匯出就看起來比較正常了。

今天先到這啦,這篇只是範例,下一篇將嘗試以SQL查詢簡單的DB來實作匯出pdf


Reference


上一篇
報表設計好朋友Jaspersoft Studio(下)-認識Parameters與Fields、設計模板內容
下一篇
JasperReports-匯出PDF
系列文
Java工程師的報表入門與實作15
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言