您好,登錄后才能下訂單哦!
在制作業務報表時,經常會遇到一些單獨依靠報表工具難以解決的問題。本文將針對幾個 Jasper 報表工具用戶在國外論壇中提出的現實問題,介紹如何用集算器 SPL 語言加以解決的方案。這里的解決方案其實并不僅適用于 Jasper,對其它報表工具也同樣適用。
數據文件 data.csv 存儲著某賬戶各期資金存取情況,在已知賬戶初始余額為 43 的情況下,需要根據該文件計算出各期余額,部分源數據如下:
Inputs,Outputs 0,10 15,0 22,0 0,33 0,15 0,14 36,0 0,69 2,0 18,0 |
想要得到的報表結果如下:
根據存取金額計算各期余額時需要進行跨行計算,可以用 Jasper 表達式實現,但實現步驟復雜且有一定難度,而通過集算器協助 Jasper 則可以輕松實現。具體的集算器 SPL 代碼如下:
A | |
1 | =file("data.csv").import@tc() |
2 | return ? (t=43,A1.derive(t=t+Inputs-Outputs:Balance)) |
A1?? 讀入文件,選項 @tc 表示文件有標題行、以逗號為分隔符。
A2?? 計算各期余額并將計算結果返回給報表。其中,設置賬戶初值 t 為 43,然后在 A1 序表中增加一個計算列,其值為上期余額 + 本期流入 - 本期流出。顯然這里的計算結果就是希望報表呈現的內容。
將以上 SPL 代碼存為文件 balance.dfx。
為了在報表中呈現計算結果,可以利用集算器對外提供 JDBC 接口。在報表工具中通過建立 JDBC 數據源引入集算器腳本,而報表調用集算器定義的方法和調用存儲過程一樣,在 Jasper 的 SQL 設計器中可以用 call balance() 來調用并傳入參數。詳細步驟請參看《JasperReport 調用 SPL 腳本》。
然后,在 Jasper 中設計最簡單的 list 表,模板如下:
預覽后可以看到報表結果,和我們要求的一樣:
?
數據庫表 loan 存儲著貸款信息,包括貸款總額、按月分期數、年利率。要求實現一張分組表,在每條貸款信息下列出各期明細,包括:當期還款額、當期利息、當期本金、剩余本金。
表 loan 的部分數據如下:
LoanID | LoanAmt | Term | Rate |
L01 | 100000 | 5 | 4.75 |
L02 | 20000 | 2 | 5 |
L03 | 500000 | 12 | 4.5 |
想要得到的報表結果如下圖:
根據貸款額計算貸款分期時需要進行循環計算和跨行計算,用存儲過程或 Scriptlets 實現的難度較大,而同樣使用集算器協助 Jasper 就可以輕松實現。編寫集算器 SPL 代碼如下:
A | |
1 | =db.query("select ? * from loan") |
2 | =A1.derive(Rate/100/12:mRate,LoanAmt*mRate*power((1+mRate),Term)/(power((1+mRate),Term)-1):mPayment) |
3 | =A2.((t=LoanAmt,Term.new(A2.LoanID:LoanID, ? A2.LoanAmt:LoanAmt, A2.mPayment:payment, A2.Term:Term,A2.Rate:Rate, ? t*A2.mRate:interest, payment-interest:principal, ? t=t-principal:principlebalance))) |
4 | =A3.conj() |
5 | return ? A4 |
A1?? 執行 SQL,取出 loan 中的記錄。
A2?? 在序表 A1 中新增計算列月利率 mRate 和每期還款額 mPayment。結果如下:
A3?? 根據貸款信息計算各期明細。A2.()是循環函數,可對 A2 的成員依次進行計算,“()”內的代碼將分步計算,最終返回最后一個逗號的計算結果。其中函數 new 用來生成新的二維表。A3 的計算結果是層次數據,如下:
A4?? 合并層次數據,形成分期明細二維表。
A5?? 返回結果給報表。
?
同樣,在 Jasper 中可以設計一張簡單的分組表,模板如下:
預覽后就可以看到需要的的報表結果了。
?
數據庫表 store 存儲著多種產品在 2014、2015 年的銷售量,需要用交叉表呈現每種產品每年的銷售量,并計算出各產品的年增長率。部分源數據如下:
Year?????? item?????? quantity 2014?? Book?? 35 2015?? Pencil 50 2014?? Pencil 56 2015?? Book?? 67 |
想要得到如下報表結果:
因為交叉表的每一列都是動態生成的,進行列間計算時又需要動態引用,因此用 Jasper 腳本實現這種需求有一定難度,而用集算器在數據準備階段實現相應的計算就相對簡單很多。集算器 SPL 代碼如下:
A | |
1 | =mydb.query("select ? * from store order by item,year") |
2 | =A1.group(item).run(A1.record(["Growth ? Rate",item,~(2).quantity/~(1).quantity-1])) |
3 | return ? A1 |
A1?? 取出 store 表的記錄。
A2?? 追加各產品的年增長率。其中,group 按產品分組,run 對每組數據依次計算,record 追加記錄,~(i)表示當前組中的第 i 條記錄。
A3?? 將計算結果返回給報表。
?
在 Jasper 中設計最簡單的交叉表,模板如下:
預覽后可以看到報表結果:
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。