深入淺出JasperReports
簡介
-
為 Java 開發的開源程式庫
-
開發易擴充的動態報表
-
具有表格、圖表、地圖、子報表等功能
-
支援匯出多種格式(docx、xls、odt、ods、pdf、html…)
-
可以通過多種方式提供數據(csv、JDBC、json…)
開發思考流程
-
了解使用者報表需求(是否需要影印,如果要,詢問紙張大小)
Page Type | Dimensions in Pixels |
---|---|
A3 |
842x1190 |
A4 |
595x842 |
A5 |
421x595 |
B4 |
709x1002 |
B5 |
501x709 |
-
思考要使用的Band
-
設定預設的Styles(記得勾Default Style)
-
加上要用的Fields & Parameters
-
思考需不需要使用Variables
-
開始設計報表(拉元件到畫面)
-
設定屬性
Band
簡介
-
十二個Band
-
Band寬度為100%,高度可以自定義
-
大部分的Band高度會自動擴增(遇到subReport,或是TextField超出時),column Footer 、page Footer、last Page Footer除外。
-
所有Band高度的總和必須小於等於整頁高度-上下的外距(margin)
-
Band三大屬性有Height、Split Type、Print When Expression
-
Split Type ,設定當該頁或該欄剩餘的空間不足以容納該 Band 時,要如何安排該 Band。
-
Split Type屬性 | 說明 |
---|---|
Stretch |
default,如果實際高度大於Band高度,超出的部分就可能被切斷。 |
Prevent |
避免被切斷,整個 Band 移到下一頁或下一欄,但如果下一頁或下一欄還是不夠高的話,還是會被切斷。 |
Immediate |
立即被切斷,該頁或該欄放不下的部份移到下一頁或下一欄,Band 會被切成兩塊以上。 |
Band介紹
Band 名稱 | 描述 |
---|---|
Title |
標題,只會在報表的第一頁最上方出現。 |
Page Header |
頁首,在報表的每一頁上面都會出現,除了第一頁是在Title底下以外,其他頁面的頁首都會在最上面。(如果有選Summary On A New Page,則最後一頁不會出現) |
Column Header |
表頭,一般用來放欄位名稱。 |
Group Header |
組表頭,如果有設定Group會出現,介於Column Header 跟 Detail中間。 |
Detail |
報表的內容,實際要呈現的內容放在這裡。Detail允許有多個Band(Detail1、Detail2、.. Detail n)。 |
Group Footer |
組表尾,如果有設定Group會出現,介於Detail 跟 Column Footer之間。如果超過一個組被定義,組表尾出現在組定義的順序相反(Group3、Group2、Group1)。 |
Column Footer |
表尾,出現在每頁Detail的下方。(如果有設定Float Column Footer就會動態的在最後一頁的Detail下方) |
Page Footer |
頁尾,出現在每個頁面的底部。 |
Last Page Footer |
最後一頁的頁尾,如果有設定會取代最後一頁的Page Footer。 |
Summary |
出現在報表最後一頁的Detail底下,可以放一些統計的東西。 |
No Data |
無資料區塊,當資料為0筆且When No Data Type設定為No Data Section,才會顯示這塊的內容。 |
Background |
用於創建浮水印用。背景部分會顯示在每一頁上,並且不能溢出到下一個頁面。放在這一部分的元素在頁面初始化的時候求值,並顯示在背景中。所有其他的頁面對象被顯示在背景上對象的頂部。用於創建浮水印用。 |
Fields & Parameters
Fields:用來顯示Datasource取回來的資料
-
Fields三大屬性
-
Name(欄位名稱)
-
Class(型別)
-
Description(說明)
-
Parameters:外部傳來的一些參數,可以用在標題字串、列印日期、判斷的boolean值等等。
-
Parameters屬性
-
Name(參數名稱,從後端傳來的變數名稱)
-
Class(型別)
-
Description(說明,可寫可不寫)
-
Is for Prompting(如果不打勾,用Preview預覽時就不會要求打參數)
-
Default Value Expression(預設的表達式)
-
Evaluation Time(決定連線前後,要執行預設表達式的時機)
-
Early:在連線前,執行預設的表達式
-
Late:在連線後,執行預設的表達式
-
-
Variables
Variables:用來儲存對某個表達式計算後的結果,可用來統計、傳遞子報表的參數。
-
Variables屬性
-
Name(參數名稱,畫面元件Expression用[$V{Name}])
-
Value Class Name(類別)
-
Calculation(要如何對表達式作計算)
-
Calculation只能做數字的計算
-
-
Calculation屬性 | 說明 |
---|---|
Nothing |
不做任何計算,直接根據表達式把值印出,可用這個做簡單的運算(ex:$P{a}+$P{b},但只能計算數字類型) |
Count |
計算有幾筆資料 |
Distinct Count |
計算有幾筆不重複的資料 |
Sum |
把資料的值累加 |
Average |
累加結果的平均值 |
Lowest |
表達式的最小值 |
Highest |
表達式的最大值 |
StandardDeviation |
根據表達式的所有值傳回標準差 |
Variance |
根據表達式的所有值傳回變異數 |
System |
可以自己控制計算方式(比如用Java程式) |
-
Expression(用來做計算的變數)
-
Initial Value Expression(Variable初始化的值,如果沒給就指向Expression的值)
-
Increment Type(Variable在什麼時候做計算)
Increment Type屬性 | 說明 |
---|---|
Report |
只有在報表的最後計算一次 |
Page |
在每頁都計算一次(每經過一個Page Header計算一次) |
Column |
在每一列都計算一次(每經過一個Column Header計算一次) |
Group |
在每一個群組計算一次,需要設定Group |
None |
每筆資料都會做運算 |
-
Reset Type(Variable在什麼時候會重置,需要設定Initial Value Expression,沒給的話,重置會變成null)
Reset Type屬性 | 說明 |
---|---|
Report |
只有在報表創建時會進行重置 |
Page |
在每頁都重置一次(每個Page Header重置一次) |
Column |
在每一列都重置一次(每個Column Header重置一次) |
Group |
在每一個群組會重置一次,需要設定Group |
None |
Variable不會被重置,所以不用設定Initial Value Expression |
-
Incrementer Factory Class Name(用來客製化計算的一個的Java類別,需要實作net.sf.jasperreports.engine.fill.JRIncrementerFactory介面)
-
假如你的Variable的Value Class Name為java.lang.Integer,但你的Expression回傳字串型別的值,這個變數的值會為0
-
-
JasperReports內建Variables
-
內建的Variables可以直接拿來使用,但無法做修改
-
Variables名稱 | 說明 |
---|---|
REPORT_COUNT |
報表到目前為止共包含幾筆資料(如果要流水編號可以用這個) |
PAGE_NUMBER |
可以顯示當前所在的頁數,也可以顯示報表的總頁數(根據TextField的evaluationTime屬性設定為Now還是Report決定要顯示什麼) |
COLUMN_NUMBER |
當前的COLUMN數(通常一頁只會有一個Column,所以為1,如果一頁有多個Column時,才會有用處) |
PAGE_COUNT |
當前頁包含幾筆資料(當前Page Header 跟 Page Footer之間的Detail裡面有幾筆) |
COLUMN_COUNT |
當前列包含幾筆資料(當前Column Header 跟 Column Footer之間的Detail裡面有幾筆) |
Subreport
Subreport 屬性
-
Run To Buttom(如果選true,該子報表會填滿該頁全部,適合子報表的內容為一筆資料一頁用)
-
Overflow Type(判斷子報表是否要超過母報表的高度)
-
Using Cache(是否快取)
-
Connection Expression or Datasource Expression(資料來源,可以是直接連DB或是用JRBeanCollectionDataSource傳資料)
-
Parameters Map Expression(可以傳一個Map當作參數進去)
-
Edit Return Values(子報表回傳的資料,通常用在傳總計或是數量)
-
Edit Parameters(傳進去子報表的資料,可以用在ID辨別)
-
Expression(子報表的檔案來源,用字串去記)
子報表Expression判斷順序
-
網址
-
同層資料夾的檔名
-
加上絕對路徑的檔案
-
不能使用相對路徑
-
參數傳遞
參數傳遞可分為從 主報表傳進子報表 和 子報表傳回主報表
子報表傳回主報表

回傳參數需要設兩個變數,一個在主報表一個在子報表,如下圖:

子報表的變數
-
Value Class Name改成跟主報表設定變數的類別一樣
-
Calculation 看你是否有要做計算,這邊是計算某欄位的總和
-
Expression 要做總和的Field,可以用三元運算子來做if判斷
-
Initial Value Expression 可以設定初始值,例如我這邊設0

主報表的變數 - Value Class Name改成跟子報表設定變數的類別一樣 - Increment type 跟 Reset type 設成 Report

主報表要放傳回變數的TextField,要將Evaluation Time改成Band,如下圖: |

問題分享
-
如果只要產製證書或申請表等只有參數的報表,將所有內容刻在Title的Band,並將該Jasper的Report設定中的When No Data Type選成 All Sections No Detail
-
有時候excel表格超過一定行數就自動跳頁,這時如果不想要自動跳頁,將report的主設定中的 Ignore Pagination 打勾,就不會幾行就自動跳頁了。如下圖:

-
如果想要產生動態欄位報表 ,可以將Appearance 裡面的 Print When Expresion 設定布林條件,決定是否要顯示該欄位,如下圖:

-
如果想要一個TextField裡有不同字體大小或顏色
-
先將TextField裡的markUp改成html,如圖:
-

-
在Expression裡面加上<font></font>,如圖:

-
也可以用<span style='font-size:16px;'>
-
如果TextField 靠右對齊時,發現離右邊框線太近時,可以用right Indent去微調靠近右邊的px,如下圖:

-
如何在japser加上正方形實心框框 ■ 或是 空心框框 □ ?
-
將textField 的 markup 改成 html,如圖:
-

-
在 expression 使用html Geometric Shapes
-
如何讓detail的每個欄位等長且與最高的欄位同高?
-
一種方法是用成一個ElementGroup
-
另一種方法是改變這些屬性
-
1. Set "Position" to "Float" 2. Set "Stretch Type" to "ContainerBottom" 3. Check "Print when detail overflows" checkbox. 4. Check the "Stretch with overflow" checkbox.
-
換行
-
staticText 欄位
-
點擊兩下該欄位,Shift + Enter 換行
-
-
textField
-
加上"\n"
-
將Markup 改成 html,用<br>
-
-
-
如何讓Field、Parameter、Variable的數字有三位一撇 ? (ex:1000→1,000)
-
將TextField的Expression加上DecimalFormat的方法format,如下圖:
-

-
背景顏色修改
-
幾乎每個Elements有一個共有的屬性-Backcolor(背景顏色),但修改後如果發現畫面沒有做修改,可能是因為Transparent(透明)選取了,此時記得將下面的transparent的打勾取消,如下圖:
-

-
在產製儲存格合併的表格時,可能會遇到分頁中間有斷行的問題。
將Detail Band的 Split Type(分裂類型) 改成 Prevent(避免),這樣就能解決子報表跳頁底線跑版的問題。

-
如果用同樣的JRBeanCollectionDataSource塞給兩個subReport,會產生第一個子報表有抓到值,而第二個沒有,這時候把子報表的資料參數改成用list接,如下:
Java裡寫
paramsMap.put("statsData", summaryList);
jrxml裡寫
<parameter name="statsData" class="java.util.List"/> ... <subreportParameter name="statsData"> <subreportParameterExpression> <![CDATA[new net.sf.jasperreports.engine.data. JRBeanCollectionDataSource($P{statsData})]]> </subreportParameterExpression> </subreportParameter> ...