2012-06-21

JasperReports 與 iReport

JasperReports 報表的生命週期:
  1. 設計:報表設計,產出 JRXML,一種 XML 檔案
  2. 編譯:將 JRXML 編譯成 JASPER 檔,並檢查語法正確性
  3. 套版:執行 JASPER 檔,讀入 Datasource,然後輸出各種格式的報表
應該不會有人直接去寫 JRXML,所以圖形化編輯工具 iReport 就出現了。

基本上,iReport 可以執行 JasperReports 報表生命週期裡的所有階段,但在與 Java 合作的系統裡,iReport 主要負責前兩個步驟來產出 JASPER 檔,然後交由 Java 呼叫 JasperReports Engine 來產出報表,第三個步驟在 iReport 裡則作為測試用。

JRXML

在 3.0.1 以前是用 jasperreport.dtd,以後改用 jasperreport.xsd。

內容可區分成兩部份,簡單講就是版面與資料:
  • 版面:版面相關的設定,例如頁面大小或欄位位置尺寸等。
  • 資料:來源有兩種,傳入參數與 Datasource,共同介面為 JRDataSource。

JASPER 檔

為了執行效能,必須先將 JRXML 編譯成 JASPER 檔,在編譯過程中必須驗證 JRXML 的語法正確性,而不是在執行時才檢查。

JASPER 檔底層事實上是 Java native bytecode,所以才能快速的執行。

JASPER 檔不包含任何外部資源,包括報表用到的圖片檔、語系檔、style 設定檔等,這些外部檔案必須要在執行時可以找得到。

Expression

JasperReports 支援三種 Expression 語言:Java、Javascript 與 Groovy,可以從 iReport 裡報表名稱按右鍵 > 屬性 > Language 做修改。

Expression 就是計算式,一個欄位的值可以來自傳入參數、變數、Datasource 或者計算式運算的結果。

Expression 一定要回傳物件,不可以沒有回傳,也不可以回傳 primitive value。

以 Java 為例,Expression 可用的運算元型別為 Boolean, Byte, Short, Integer, Long, Float, Double, String, Date 與 Object。

Expression 可使用的報表物件,是物件格式,不是 primitive value(只限 Java)
  • $F{field_name} - 資料庫欄位
  • $V{variable_name} - 變數
  • $P{parameter_name} - 參數
  • $R{resource_key} - i18n
Expression 可用的運算子就是一般的運算子,例如 +、-、*、/、%、||、&&、==、!=、! 等。

Expression 可以呼叫物件的 method,但僅限於有回傳值的 method。

Expression 唯一可以使用的邏輯判斷語法為 aaa ? bbb : ccc,還可以巢狀使用。

Expression 可以使用括弧來組織複雜的計算式。
$F{age}  < 18 ? ($F{name}.contains("Neil") ? $F{age} : 0) : $F{age}

Expression 可以呼叫自訂的 static Java method。
MyFormatter.formatDate($F{theDate})
正確的 Java Expression 用法:
  • "A String"
  • new Integer(116)
  • new Boolean(false)
  • $P{name}.equals("Neil") ? "Neil" : "Nail"
錯誤的 Java Expression 用法:
  • 11 + 6
  • true 
  • $P{age} == 116 ? "Neil" : "Nail"
兩個重點:
  • 一定要回傳,且要回傳物件格式
  • $F、$P、$V、$R 都是物件,這就是第三個錯誤用法失敗的原因
但是,物件與 primitive value 的問題只存在 Java,Javascript 與 Groovy 沒這問題。

使用 Java 作為 Expression 的 language 就得處處以物件格式做思考,若是用 Groovy 或者 Jav ascript,就可以直接用加減乘除做運算,不用做型別轉換。

JasperReports 仍未支援 Javascript 某些 function,但可以混合 Java 使用。
(new java.lang.String('Neil')).startWith("N");
另外,Javascript 在瀏覽器裡是執行期解析,會有效能問題,但在 JasperReports 裡則是在編譯時,就已經轉為 Java byte code 了,所以不會有效能問題。


沒有留言:

張貼留言