iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
Software Development

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

JasperReports-匯出含Excel公式的報表

  • 分享至 

  • xImage
  •  

大家在使用Excel的時候,最常用的功能之一莫過於Excel的公式,如果把Excel公式寫好,即使幾個單元格數字有變動,整張Excel的數字都會動態改動,非常方便。
而前面介紹的JasperReports所匯出的Excel只是後端程式計算好的數字,匯出來的Excel就缺少了公式的靈活性,不過要做的話,JasperReports還是做得到喔~

情境:報價單

以一個簡易的報價單為例(如下圖),希望金額欄位以及合計單元格使用Excel公式計算的話要怎麼設定呢?

設計報表模板

模板的佈局一樣是欄位名稱放Column Header,Fields放Detail,由於Excel不分頁,合計放Page Footer或Summary都可以,要放公式的金額欄位與合計單元格都先空著。

自動遞增的序號

在這個報價單例子中,序號僅僅是編號,沒有商業邏輯,因此不想寫在後端程式中的話,可以利用JasperReports-為報表加上頁碼這篇所介紹的預設變數COLUMN_COUNT來顯示當前資料列數

設定Excel公式

添加屬性:

  • 選取金額的Text Field -> 選取右下屬性區域「Appearance」 -> 點擊最下方「Edit Properties」 -> 打開屬性視窗後點擊右側「Add」
  • 在添加屬性的視窗中的「Property Name」打上net.sf.jasperreports.export.xls.formula

表達式:

  • 金額: [金額 = 數量 * 單價],數量與單價都可以由Field取得,因此表達式可寫為$F{quantity} + "*" + $F{price}
  • 合計: [合計 = SUM(金額)],這項就比較麻煩了,因為金額也是用公式計算出來的,沒有Field可以取值,且依DataSource動態增長,只能取Excel單元格的位置來用。
    • 金額是在第五欄第四列開始有值,對應到Excel是「E4」,要加到合計的前一列,例如有4列項目資料,合計的公式應為「SUM(E4:E7)」,可以發現「E7」就是「起始列(4) + 序號(4) - 1」
    • 報表生成到Page Footer時Detail都跑完了,因此$V{COLUMN_COUNT}會是最後一個序號的值,表達式可以寫為"SUM(E4:E" + (4 + $V{COLUMN_COUNT} - 1) + ")"

DataSource

新增一些範例DataSource

@Data
@AllArgsConstructor
public class QuotationModel {
    private String item;

    private Integer quantity;

    private BigDecimal price;
}
QuotationModel quotationModel1 = new QuotationModel("原子習慣", 2, new BigDecimal(260));
QuotationModel quotationModel2 = new QuotationModel("被討厭的勇氣", 1, new BigDecimal(300));
QuotationModel quotationModel3 = new QuotationModel("阿德勒心理學講義", 10, new BigDecimal(268));
QuotationModel quotationModel4 = new QuotationModel("新制多益TOEIC聽力/閱讀題庫解析", 1, new BigDecimal(1232));
List<QuotationModel> quotationModelList = new ArrayList<>();
quotationModelList.add(quotationModel1);
quotationModelList.add(quotationModel2);
quotationModelList.add(quotationModel3);
quotationModelList.add(quotationModel4);

報表參數

Map<String, Object> parametersMap = new HashMap<>();
LocalDate date = new Date().toInstant()
        .atZone(ZoneId.systemDefault()).toLocalDate();
parametersMap.put("date", date
        .format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));

匯出報價單Excel

匯出的步驟與之前的範例相同,直接看看結果吧


可以看到金額與合計欄位都已經是Excel的公式,可以自動計算價錢囉


Reference


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

尚未有邦友留言

立即登入留言