1. 程式人生 > >JasperReport報表開發之轉置交叉表

JasperReport報表開發之轉置交叉表

for 不同的 結構 整理 result 無需 nbsp 數據 img

使用Jasper或BIRT等報表工具時,常會碰到一些很規的統計,用報表工具本身或SQL都難以處理,比方源數據不符合交叉表的要求,須要轉置後再呈現。

集算器具有結構化強計算引擎,集成簡單。能夠協助報表工具方便地實現此類需求。以下通過一個樣例來說明轉置交叉表的實現過程。

數據庫表booking匯總著各年度商品的預定數據。有四個字段,包含年份和三種預定狀態,部分數據例如以下:

技術分享

報表要求呈現指定年份及上一年的預定情況。當中行組有三項,即三種預定狀態,列組是年份。測度是當年的預定數據。此外要匯總出指定年份各預定狀態的增長率。表例子如以下:

技術分享

能夠看到,這張報表的難點是:源數據無法直接用於交叉表,匯總列要用相對位置來動態計算。

假設能將源數據轉置。並將匯總列事先計算出來,則會顯著減少難度,比方以下這樣:

技術分享

以下用集算器準備報表所需的數據,代碼例如以下:

技術分享

A1=yearBegin=yearEnd-1

yearEnd是來自報表的參數,表示用戶指定的年份,比方2014。A1中的代碼用來計算上一年(比方2013),為了方便引用,上一年定義為yearBegin。

A2=myDB1.query(“select * from booking where year between ? and ?

order by year desc”,yearBegin,yearEnd)

這句代碼用來從數據庫查出指定年份及上一年的數據。myDB1是數據源名,指向MYSQL。函數query可運行SQL語句,也能夠接受參數。如果yearEnd=2014,則A2的計算例如以下:

技術分享

A3=create(row,col,value)

這句代碼用來新建序表A3。

A3有三個字段:row、col、value,將來可存儲整理之後的數據。新建後的A3例如以下:

技術分享

須要註意的是。序表類似數據庫結果集,也是結構化二維表。但序表是泛型的,同一個字段能夠存儲不同的數據類型,序表也是有序的,能夠按序號訪問數據。

利用序表的這些特點能夠方便地實現本案例。

A4: for ["visits","bookings","successfulbookings"]

這句代碼對集合["visits","bookings","successfulbookings"]進行循環訪問,在循環中向A3追加數據。終於準備出報表須要的數據。

for語句的作用範圍是B4-C7,用自然的縮進就能夠表示。無需括號或begin/end等標記。

在作用範圍裏能夠用A4來引用循環變量,即for語句所在單元格的格名。比方進行第一遍循環時。A4的值等於”visits”。

以下看循環體中的代碼。

B4=endValue=eval(“A2(1).”+A4)

這句代碼可從A2動態地取出第一條記錄的預定狀態數據。

函數eval可將字符串解析為表達式,比方第一遍循環時。“A2(1).”+A4會被解析為A2(1).visits,計算結果是500。當中“A2(1)”表示第一條記錄,“.visits”表示取出該記錄的visits字段。即下圖紅框處:

技術分享

C4=beginValue=eval(“A2(2).”+A4)

和endValue類似,beginValue從A2中動態地取出第二條記錄的預定狀態數據。第一遍循環時,endValue等於400。

B5=A3.insert(0,A4,A2(1).year,endValue)

C5=A3.insert(0,A4,A2(2).year,beginValue)

這兩句代碼向A3追加記錄。函數insert能夠向序表插入記錄。第一個參數能夠指定插入的位置,假設這個參數為0,則表示在最後追加記錄。

比方第一遍循環時,B5追加的記錄是:”visits”、2014、500,C5追加的記錄是”visits”、2013,400。追加後A3例如以下:

技術分享

B6=endValue/beginValue-1

這句代碼計算指定年份的增長率,比方第一遍循環時,B6=500/400-1=0.25。

C6=if(B6>0:”+”,B6<0:”-”)+string(B6,”#%”)

這句代碼用來格式化B6。算法是:假設B6大於0,則在百分數前面加“+”號,假設小於0,則加“-”號。比方第一遍循環時,C6=”+25%”。註意:格式化數據適合用報表實現,所以本步驟並不是必須。

B7=A3.insert(0,A4,string(yearEnd)+”/”+string(yearBegin),C6)

這句代碼向A3追加新記錄,比方第一遍循環時,插入的記錄是”visits”,”2014/2013”,”+25%”。例如以下圖:

技術分享

值得註意的是。這次插入的記錄都是字符串。和之前的類型不同。

整個循環運行後,報表須要的數據就會所有追加在A3中,例如以下:

技術分享

result A3
這句代碼將A3返回給報表工具。集算器對外提供JDBC接口。報表工具會將集算器識別為普通數據庫,集成方案請參考相關文檔。

接下來以JasperReport為例設計一張簡單的交叉表。模板例如以下:

技術分享

報表中須要定義一個參數pyearEnd,用來相應集算器中的參數。

預覽後能夠看到報表結果:

技術分享

報表調用集算器的方法和調用存儲過程一樣。比方將本腳本保存為booking.dfx,則在JasperReport的SQL設計器中能夠用booking $P{pendYear}來調用。

JasperReport報表開發之轉置交叉表