天天看點

JasperReport Tutorial(翻譯)-

JasperReport Tutorial(翻譯)- -

JasperReport是一個強大的開源報表工具,它可以

1. 簡介

JasperReport是一個強大的開源報表工具,它可以傳送豐富的報表内容到顯示器、列印機或者PDF、HTML、XLS、CSV、XML檔案。它完全使用Java編寫,可以在各種Java應用中用來建立動态報表内容。它的主要目标是用簡單靈活的方法幫助建立便于列印的分頁文檔。

JasperReport根據一個xml報表設計檔案來組織從JDBC獲得的關系資料庫資料。要用資料填充報表,首先必須編譯報表。編譯xml的報表設計檔案是用JasperManager類的compileReport()方法完成的。

通過編譯,報表設計被加載到一個報表設計對象(net.sf.jasperreports.engine.JasperReport類的執行個體)中并被序列化然後儲存。在應用程式用資料填充報表時使用該序列化檔案。實際上,報表編譯完成了報表設計中所有的java表達式的編譯。很多檢查工作在編譯期間進行以確定報表設計的完整性,編譯後的檔案是待填充的報表,以友善應用程式用各種資料集來産生不同的報表文檔。

要填充報表,可以使用JasperManager類的fillReportXXX()方法。這些方法接受一個參數代表報表設計——可以是一個JasperDesign對象,也可以是一個存放該類對象的檔案名——還有一個獲得填充報表資料的JDBC連接配接。報表填充的結果是一個表示待列印文檔的對象(net.sf.jasperreports.engine.JasperPrint類的執行個體),可以被序列化儲存以後繼續使用,或者傳送給列印機、顯示器,或者導出成PDF、HTML、XLS、CSV或者XML檔案。

2. 報表設計

一個報表設計表示一個模版用來被JasperReport引擎填充資料并傳送到螢幕、列印機或者Web。資料庫的資料根據報表設計被組織來填充報表以得到待列印的分頁文檔。報表設計都儲存到一個特定結構的一個XML檔案中,檔案結構定義在一個JasperReport引擎可以識别的DTD檔案中。然後這些xml檔案會被編譯以準備報表填充操作。

建立一個報表設計(模版),必須按照如下結構編輯一個xml檔案:

<?xml version="1.0"?>
      
<!DOCTYPE jasperReport 
      
  PUBLIC "-//JasperReports//DTD Report Design//EN" 
      
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
      
<jasperReport name="name_of_the_report" ... >
      
...
      
</jasperReport>
      

3. 報表參數

報表參數是傳遞給報表填充操作的對象的引用,為報表引擎傳遞它無法在資料源中找到的資料是非常有用的。例如,我們可以将登陸執行報表填充操作的使用者名傳給引擎,這樣我們可以在報表上顯示制表人或者動态改變報表的标題。

一個使用報表參數的重要作用是完成報表的動态查詢語句,以使報表獲得的資料更加符合要求,這些參數就像報表資料的過濾器。

在報表中聲明參數非常簡單,隻需要指定名稱和類型(java類):

<parameter name="ReportTitle" class="java.lang.String"/>

<parameter name="MaxOrderID" class="java.lang.Integer"/>

<parameter name="SummaryImage" class="java.awt.Image"/>

可以用兩種方法在查詢語句中使用報表參數:

1.         就像通常在java.sql.PreparedStatement中使用參數一樣:

SELECT * FROM Orders WHERE OrderID <= $P{MaxOrderID} ORDER BY ShipCountry

2.         有時需要用參數來動态改變SQL查詢的部分語句或者将整個SQL語句作為參數傳給報表,在這種情況下,文法有一點不同,如下:

SELECT * FROM Orders ORDER BY $P!{OrderByClause}

還有一些報表内建的系統參數可以直接在表達式中使用:

REPORT_PARAMETERS_MAP

REPORT_CONNECTION

REPORT_DATA_SOURCE

REPORT_SCRIPTLET

4. 資料源

JasperReport隻是各種類型的資料源,并提供一個JRDataSource的接口。該有一個預設的實作類(JRResultSetDataSource class)包裝了ResultSet對象,允許使用任何通過JDBC連接配接的資料庫。使用JDBC資料源時,即可以通過将資料庫連接配接傳給報表填充引擎并在報表定義中指定一個SQL查詢語句(參考dtd定義中的<queryString>元素)來提供資料,也可以直接用ResultSet作參數生成JRResultSetDataSource對象來提供資料。

對于其他的資料源,也不會太麻煩,隻需要實作JRDataSource接口來建立自己的資料源類。

5. 字段

報表字段提供了唯一映射資料源中資料到報表資料的方式。如果資料源是ResultSet對象,報表字段必須對應ResultSet對象中的列,就是說報表字段必須和對應的列有相同的名字和比對的類型。

例如,我們要建立的報表需要用Employees表的資料,該表結構如下:

Column Name      Datatype       Length
      
--------------------------------------
      
EmployeeID       int             4
      
LastName         varchar        20
      
FirstName        varchar        10
      
HireDate         datetime        8
      

我們可以在報表設計檔案中定義如下的字段:

<field name="EmployeeID" class="java.lang.Integer"/>
      
<field name="LastName" class="java.lang.String"/>
      
<field name="FirstName" class="java.lang.String"/>
      
<field name="HireDate" class="java.util.Date"/>
      

如果我們生命一個報表字段在ResultSet中沒有對應的列,則會在運作時抛出異常。當然ResultSet中的列沒有被聲明為報表字段不會影響報表的資料填充,但是他們仍然是可以通路的。

6. 表達式

表達式是JasperReport的一個很強大有用的特性。用表達式可以:聲明報表變量來完成各種計算,為資料分組,指定報表文本字段内容或對其他報表對象的顯示進行更靈活的定制。基本上,所有的報表表達式都是Java表達式,并且可以引用報表字段和報表變量。

在報表設計的xml檔案中有諸多定義表達式的元素:<variableExpression>, <initialValueExpression>, <groupExpression>, <printWhenExpression>, <imageExpression> 和<textFieldExpression>。

要在在表達式中引用報表字段,字段名必須寫在$F{和}符号之間。例如,如果我們要在一個文本域中連接配接兩個字段,我們可以像下面定義表達式:

<textFieldExpression>
      
  $F{FirstName} + " " + $F{LastName}
      
</textFieldExpression>
      

表達式可以更複雜:

<textFieldExpression>
      
  $F{FirstName} + " " + $F{LastName} + " was hired on " + 
      
  (new SimpleDateFormat("MM/dd/yyyy")).format($F{HireDate}) + "."
      
</textFieldExpression>
      

要在表達式中引用一個變量,必須将變量名寫在$V{和}符号之間,如下:

<textFieldExpression>
      
  "Total quantity : " + $V{QuantitySum} + " kg."
      
</textFieldExpression>
      

對于報表參數也是同樣的文法,隻不過參數名必須寫在$P{和}符号之間:

<textFieldExpression>
      
  "Max Order ID is : " + $P{MaxOrderID}
      
</textFieldExpression>
      

7. 變量

報表變量是在表達式之前建構的專用對象。變量隻聲明一次,而可以在整個報表設計中重複使用,并在對應的表達式中完成大量的計算,進而簡化了報表設計。在表達式中,一個變量可以引用其它變量,但是被引用變量必須在引用變量之前聲明。是以變量的聲明順序對報表設計也是很重要的。

變量還可以聲明來完成引擎内建計算的求值,如:count、sum、average、lowest、highest、variance等等。一個完成Quantity字段sum計算的變量定義如下:

<variable name="QuantitySum"

    class="java.lang.Double" calculation="Sum">

  <variableExpression>$F{Quantity}</variableExpression>

</variable>

我們還可以通過制定初始化級别來改變計算過程,預設的級别是Report就是變量僅在報表開始處初始化一次,一直到報表結束完成計算。我們可以選擇更低的級别讓變量在每個Page、Column或者Group級别重新初始化。假如我們想計算計算每頁的總數,變量聲明如下:

<variable name="QuantitySum" class="java.lang.Double" 
      
          resetType="Page" calculation="Sum">
      
  <variableExpression>$F{Quantity}</variableExpression>
      
  <initialValueExpression>new Double(0) </initialValueExpression>
      
</variable>
      

變量将在每一頁的開始處被初始化為0。

引擎還提供了如下的内建變量可以在表達式中直接使用:

PAGE_NUMBER

COLUMN_NUMBER

REPORT_COUNT

PAGE_COUNT

COLUMN_COUNT

GroupName_COUNT

8. 報表區域

在建立報表模闆時,我們需要定義報表區域的内容和風格。一個完全的報表模闆包括如下幾個區域:<title>, <pageHeader>, <columnHeader>, <groupHeader>, <detail>, <groupFooter>, <columnFoter>, <pageFooter>, <summary>。區域是報表的重要組成部分,它有指定的高度和寬度,并且可以容納直線、矩形、圖檔或者文本域等報表對象。我們用<band>标簽在報表模闆xml檔案中定義報表區域的内容和風格。下面是一個PageHeader區域的定義,它僅僅包含一條直線和一個靜态文本:

<pageHeader>
      
  <band height="30">
      
    <rectangle>
      
      <reportElement x="0" y="0" width="555" height="25"/>
      
      <graphicElement/>
      
    </rectangle>
      
    <staticText>
      
      <reportElement x="0" y="0" width="555" height="25"/>
      
      <textElement textAlignment="Center">
      
        <font fontName="Helvetica" size="18"/>
      
      </textElement>
      
      <text>Northwind Order List</text>
      
    </staticText>
      
  </band>
      
</pageHeader>
      

9. 分組

組表示一種分組組織資料的方式。填充報表資料時,JasperReport引擎計算所有定義的分組表達式檢查是否出現組邊界(表達式的值改變),如果遇到組邊界則将<groupFooter>和<groupHeader>報表區域加入報表。

報表可以包含任意多的分組,組在報表中的聲明順序很重要,因為組之間互相包含。一個組包含其後聲明組依此類推,一個大的組遇到邊界,所有的子組都将被重新初始化。一個報表組跟其資料分組表達式一起定義,同時還需要定義兩個報表分組區域:分組頭區域和分組尾區域。

關于分組的詳細資訊參考分組的報表示例。

10.              字型和Unicode 支援

現在你可以用任何語言來建立報表。<font>元素的新屬性允許在Java字型和PDF字型間映射。PDF使用特定的字型集使得以前的JasperReport版本沒有辦法使用它們。新的屬性使使用者可以指定什麼PDF字型用來顯示不同的字元集(pdfFontName屬性),什麼編碼類型(pdfEncoding屬性)和是否将字型嵌入PDF文檔(isPdfEmbedded)。

為了台灣字型集的使用,增加了一個新屬性<reportFont>。報表字型是報表級别的字型定義用來作為報表中其他顯示對象的預設字型。因為對國際字元集的支援不知為何被綁定到iText庫,你可以在iText documentation.文當中找到更多關于如何用不同的語言不同的字元集建立PDF文檔的資訊。

11.              Scriptlets

所有的報表顯示資料來自報表變量和報表字段,這些資料可以用報表變量和表達式來處理。

有時候報表需要對變量進行特殊處理,一些變量可能在報表的某個事件中(報表開始、換頁或者換列)被重新初始化,而且,變量在每次從資料源中獲得資料時(每一行)都被計算。而僅僅用簡單變量表達式無法實作所有的複雜功能,這時就要使用Scriptlet。

因為Scriptlet主要和報表變量一起工作,完全控制scriptlet的執行時機非常重要。JasperReport允許根據報表事件定制Java編碼BEFORE或者AFTER:Report、Page、Column和Group的初始化來執行Scriptlet。

要使用Scriptlet,開發者隻需要通過繼承net.sf.jasperreports.engine.JRAbstractScriptlet或者net.sf.jasperreports.engine.JRDefaultScriptlet來建立Scritplet類。該定制的Scriptlet類會被指定為<jasperReport>的scritpletClass屬性的值。建立Scriptlet時開發這需要實作或者重載如beforeReportInit(), afterReportInit(), beforePageInit(), afterPageInit(), beforeGroupInit(), afterGroupInit(),等方法。這些方法将在填充資料時被引擎在适當的時候調用。

有一個叫做REPORT_SCRIPTLET的預設報表參數表示對報表引擎在填充資料時執行個體化的Scriptlet對象的引用。它可以在整個報表的任何表達式中使用來調用Scriptlet的特定方法使整個報表機制更加靈活。

12.              子報表

子報表是報表工具的重要特性,它允許建立更複雜的報表并簡化設計工作。自報表在建立主從報表時特别有用。