iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
Software Development

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

JasperReports-報表沒有資料時的處理

  • 分享至 

  • xImage
  •  

在匯出報表的時候,有些情境下我們的DataSource是null,例如我想查詢一段日期區間的資料,但資料庫沒有此日期區間的資料,這時候要匯出什麼樣的報表,就看當時需求而定了。這一篇將會介紹幾種表示無符合資料的方式~

情境:查詢一段日期區間的學生考試成績資料

這種查詢一段日期區間的資料匯出為報表時,最容易出現查不到符合資料的情況,就以「學生考試成績資料」的模板來舉例,我將Title放入考試日期,用startDate與endDate兩個參數表示這個報表所顯示的考試日期起始日與結束日,以"考試日期:" + $P{startDate} + " ~ " + $P{endDate}表示。

前端傳日期參數

我以一個簡易的Vue專案,使用vue-datepicker套件顯示日期選擇器,方便demo與說明,如何傳到後端就不在這次討論的重點了。

  • 左邊是startDate起始日,右邊是endDate結束日

後端處理資料

原始資料

學生的考試資料在score這個table中,考試日期資料範圍從2022-01-01到2024-12-29(先忽略學生有未來人這件事)

後端接收日期參數,以WHERE條件篩選資料

當我點選下載報表按鈕,執行下載報表API,後端的物件接收前端的日期參數後,以WHERE篩選startDate到endDate的日期範圍,查詢到的資料以List的型別回傳。

WHERE Test_Date BETWEEN startDate AND endDate;

匯出Excel報表生命週期

匯出Excel的方法如下:

public static byte[] templateToExcelByte(List dataSourceList, String reportPath, Map<String, Object> parametersMap) throws Exception {

    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
        // 以JasperCompileManager將jrxml模板編譯成jasper文件
        JasperReport jasperReport = JasperCompileManager
            .compileReport(ExportReportUtil.class.getResourceAsStream(reportPath));

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

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

        // 匯出
        SimpleXlsxReportConfiguration xlsxReportConfiguration = 
            new SimpleXlsxReportConfiguration();
        // setDetectCellType使excel偵測這個值的型別並轉換為對應的格式
        xlsxReportConfiguration.setDetectCellType(true);

        JRXlsxExporter exporter = new JRXlsxExporter();
        exporter.setConfiguration(xlsxReportConfiguration);
        exporter.setExporterInput(new SimpleExporterInput(print));
        exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(byteArrayOutputStream));
        exporter.exportReport();

        return byteArrayOutputStream.toByteArray();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

匯出結果

有資料的結果

先查詢一定有資料的2024-09-01到2024-09-30這個區間。

正常顯示的結果如下:

無資料的結果,When No Data Type屬性

我以2021年的時間區間為例,這時候查詢出的dataSource是null或是空的List(new ArrayList())

在Jaspersoft Studio的右下屬性區域中,可以找到一個設定「When No Data Type」的下拉選單,這些屬性就是設定dataSource無資料時的處理方式。

  • All Sections No Detail: dataSource無資料時會顯示報表的所有部分(如標題、頁首和頁尾),但不會顯示任何Detail Band的部分,因為仍然能看到標題與欄位名稱,能夠不以任何訊息就讓人了解這是沒有資料的報表

  • No Data Section: 如果選擇No Data Section,就需要設計一個在dataSource無資料時的情況下,可以在報表顯示的訊息。

    • 我們可以在左下區域找到一個Band叫做「No Data」,這是專門用於No Data Section的Band
    • 在「No Data」點選Add Band之後,No Data Band就會出現在報表模板最下方,只有選擇No Data Section且dataSource真的無資料時才會顯示這個Band的內容
    • 我在No Data上放入static text,並填入我想說明無資料情形的顯示文字,當dataSource無資料時就會顯示這個Band的元素與文字了

  • No Pages: dataSource無資料時,報表完全不生成任何頁面

  • Blank Page: dataSource無資料時,生成一個空白的頁面
    選擇No Pages或Blank Page對於excel報表來說都是空白的excel檔,也許在pdf、word比較能感受到差異,不過在實際專案中一個空白的檔案比較容易讓人摸不著頭緒,建議搭配前端的Dialog訊息會比較明確。


Reference


上一篇
JasperReports-匯出多個sheet的Excel
下一篇
JasperReports-SubReport 子報表(上)
系列文
Java工程師的報表入門與實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言