深入淺出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> ...