欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
jasperreport使用介紹(收藏)--大家一起來(lái)學(xué)JAVA
用戶(hù)手冊的翻譯及心得體會(huì )

1 簡(jiǎn)介

JasperReport是一個(gè)強大、靈活的報表生成工具,能夠展示豐富的頁(yè)面內容,并將之轉換成PDF,HTML,或者XML格式。最重要的是它是開(kāi)源的,這給我們帶來(lái)很大方便,但是文檔卻要錢(qián),讓人不爽。不過(guò)人總要生存,再說(shuō),做這么一個(gè)好東西,用戶(hù)總不能一點(diǎn)代價(jià)也不付(雖然對于中國普通程序原來(lái)說(shuō)太貴了點(diǎn))。它還有一個(gè)相關(guān)的開(kāi)源工程—IReport,這是一個(gè)圖形化的輔助工具,因為JasperReport僅提供了可使用的類(lèi)庫而未提供更好的開(kāi)發(fā)工具,IReport的出現解決了這一難題。它們配合使用將會(huì )更大程度的提高效率。

該庫完全由Java寫(xiě)成,可以用于在各種Java應用程序,包括J2EE,Web應用程序中生成動(dòng)態(tài)內容。它的主要目的是輔助生成面向頁(yè)面的(page oriented),準備付諸打印的文檔。
JasperReport借由定義于XML文檔中的report design進(jìn)行數據組織。這些數據可能來(lái)自不同的數據源,包括關(guān)系型數據庫,colleCTions,java對象數組。通過(guò)實(shí)現簡(jiǎn)單的接口,用戶(hù)可以將report library插入到訂制好的數據源中,在以后我們將提到有關(guān)內容。
其實(shí)這是一份JasperReport Ultimate Guide的簡(jiǎn)單翻譯以及我的理解和例子。在最后,我將描述一個(gè)我正在做的工程,將其中用到的相關(guān)信息貢獻出來(lái)。我這么做是因為當我在學(xué)這個(gè)類(lèi)庫的時(shí)候苦于很少有相關(guān)的中文文檔,誘惑語(yǔ)焉不詳,希望其他人不再受苦。這個(gè)文檔將分幾次貼出來(lái),與原文檔的章節相對應。這份文檔的Word形式將在全部完成之后放在我的公開(kāi)郵箱中與各位共享。我的EMail是jxuedi@gmail.com有什么意見(jiàn)或想法請與我聯(lián)系。
閑言少敘,進(jìn)入正題。
2 API概覽

上圖為一個(gè)生成報表并打?。▽С觯┑娜^(guò)程。我將會(huì )把涉及到的重要的類(lèi)進(jìn)行一一說(shuō)明。
Class net.sf.jasper.engine.design.JasperDesign
這是一個(gè)未經(jīng)加工的報表實(shí)例,供JasperReport Library使用。這個(gè)類(lèi)可以在JasperReport類(lèi)庫內置的XML解析器對XML report design進(jìn)行解析處理之后得到。如果你的程序不想對直接X(jué)ML文件進(jìn)行操作,在例子noxmldesign中有不使用XML設計文件而動(dòng)態(tài)生成這個(gè)類(lèi)的方法。我們稍稍看看這個(gè)例子:
import 略
public class NoXmlDesignApp
{
private static JasperDesign getJasperDesign() throws JRException
{
//JasperDesign定義JasperDesign的頭信息
JasperDesign jasperDesign = new JasperDesign();
jasperDesign.setName("NoXmlDesignReport");
.剩余

//Fonts定義使用到的字體
JRDesignStyle normalStyle = new JRDesignStyle();
normalStyle.setName("Arial_Normal");

//Parameters 定義Parameters的內容—這個(gè)內容以后會(huì )提到
JRDesignParameter parameter = new JRDesignParameter();
parameter.setName("ReportTitle");
parameter.setValueClass(java.lang.String.class);
jasperDesign.addParameter(parameter);

parameter = new JRDesignParameter();
parameter.setName("OrderByClause");
parameter.setValueClass(java.lang.String.class);
jasperDesign.addParameter(parameter);

//Query 定義查詢(xún)
JRDesignQuery query = new JRDesignQuery();
query.setText("SELECT * FROM Address $P!{OrderByClause}");
jasperDesign.setQuery(query);

//Fields
JRDesignField field = new JRDesignField();
field.setName("Id");
field.setValueClass(java.lang.Integer.class);
jasperDesign.addField(field);

//Variables 定義變量
JRDesignVariable variable = new JRDesignVariable();
variable.setName("CityNumber");
variable.setValueClass(java.lang.Integer.class);
variable.setResetType(JRVariable.RESET_TYPE_GROUP);

//Groups 定義組
group.setMinHeightToStartNewPage(60);
expression = new JRDesignExpression();
//余下定義一個(gè)文檔的其他內容,這里省略

return jasperDesign;
}
從getJasperDesign()方法我們可以看出,這個(gè)應用程序并沒(méi)有從XML文件里面將report design提取出來(lái)在生成JasperDesign類(lèi),而是直接利用JasperDesign提供的函數生成了一個(gè)報表設計。這樣做的原因是基于靈活性的考慮,你可以在程序中隨時(shí)動(dòng)態(tài)生成報表,而不需要去從硬盤(pán)網(wǎng)絡(luò )中讀取XML設計文件。但通常我不這么做,因為比較麻煩,而且要對JasperReport的每個(gè)元素都非常熟悉才行。
Class net.sf.jasper.engine.JasperReport
這個(gè)類(lèi)的實(shí)例包含了一個(gè)經(jīng)過(guò)編譯的report design對象。生成它的時(shí)機是對報表編譯之后,但尚未對其填入數據的時(shí)候。編譯過(guò)程中,JasperReport需要生成一個(gè)臨時(shí)的類(lèi)文件,用以保存report expression,如變量表達式,文本,圖像表達式,組表達式等等。這個(gè)臨時(shí)的Java Source File是被動(dòng)態(tài)編譯的,編譯器使用的是JDK中用來(lái)執行應用程序的編譯器類(lèi)(compiler class)。如果 tools.jar不在classpath中,編譯過(guò)程將采用javac.exe來(lái)進(jìn)行后臺編譯。編譯后所得的字節碼保存在JasperReport類(lèi)中,用來(lái)在執行期裝填數據(filling the report with data)和給表達式賦值(evaluate various report expression)。
Class net.sf.jasper.engine.JasperCompileManager
這是一個(gè)上面提到的與編譯有關(guān)的類(lèi)。利用它提供的一些方法,你將有能力編譯從本地硬盤(pán)或一個(gè)Input Stream獲得的XML report;還可以通過(guò)傳給JasperCompileManager一個(gè)JasperDesign類(lèi),來(lái)對內存中的report design進(jìn)行編譯—功能很強大。
Class net.sf.jasper.engine.JasperPrint
當一個(gè)報表已經(jīng)裝填好數據之后,這個(gè)文檔就以JasperPrint類(lèi)的實(shí)例出現。這個(gè)類(lèi)可以直接用JasperReport內置的viewer進(jìn)行查看,也可以序列化到硬盤(pán)以備后用,或者發(fā)送到網(wǎng)上去。這個(gè)類(lèi)的實(shí)例是報表裝填過(guò)程后的產(chǎn)物,它可以被JasperReport類(lèi)庫中的導出方法導出成各種流行的格式—PDF,HTML,XML等等。
Interface net.sf.jasper.engine.JRDataSource
這個(gè)類(lèi)與報表的數據源有關(guān)。只要能夠恰當的實(shí)現他的一些接口,用戶(hù)就可以在報表中使用各種數據源,在報表裝填的時(shí)候由報表引擎負責對數據進(jìn)行解釋和獲取。當報表裝填的時(shí)候,報表引擎都會(huì )在后臺生成或提供一個(gè)該接口的實(shí)例。
Class net.sf.jasper.engine.JRResultSetDataSource
這是一個(gè)JRDataSource的缺省實(shí)現,因為很多報表數據都來(lái)源于關(guān)系數據庫,所以JasperReport缺省包含了這個(gè)外覆(wrap)了java.sql.ResultSet對象的實(shí)現。
這個(gè)類(lèi)可以用來(lái)包裹(wrap)用以對報表進(jìn)行裝填的、已經(jīng)載入的結果集,也可以被報表引擎用來(lái)包裹通過(guò)JDBC執行完查詢(xún)后所得的數據----非常有用。
Class net.sf.jasper.engine.data.JRTableModelDataSource
顧名思義,這個(gè)類(lèi)用于包裹java.swing.table.TableModel類(lèi)中的數據,它也是實(shí)現了JRDataSource接口,用于在Java Swing程序中使用已經(jīng)被載入到table中的數據來(lái)生成報表。
Class net.sf.jasper.engine.JREmptyDataSource
這是JRDataSouce接口的最簡(jiǎn)單實(shí)現,這個(gè)類(lèi)用在不需要顯示數據源數據而從參數中獲取數據的報表和僅需要知道數據源中的實(shí)際行數(number of virtual rows)的報表中。
JasperReport自帶的例子:fonts,images,shapes和unicode中使用這個(gè)類(lèi)對報表進(jìn)行裝填,來(lái)模擬沒(méi)有任何record的數據源,這時(shí)所有的field都為null。例如:
JasperRunManager.runReportToPdfFile(fileName, null, new JREmptyDataSource());
Class net.sf.jasper.engine.JasperFillManager
這個(gè)類(lèi)用來(lái)實(shí)現報表的數據裝填。這個(gè)類(lèi)提供了很多方法來(lái)接受各種類(lèi)型的report design--可以是一個(gè)對象,一個(gè)文件,或一個(gè)輸入流。它的輸出結果也是多樣的:file,Object,output Stream。
report的裝填引擎需要接收一個(gè)可以從中獲取數據和value的數據源作為報表參數。參數值(Parameters value)通常使用Java.util.Map來(lái)提供,里面包含的KEY是報表的參數名。
數據源可以通過(guò)兩種方式提供,這取決于你的解決方案
通常情況下,用戶(hù)應該提供一個(gè)JRDataSource對象,例如我前面提到的那些。
但是大多數的報表都是采用關(guān)系數據庫中的值來(lái)裝填數據,所以JasperReport擁有一個(gè)內置的缺省行為—讓用戶(hù)在報表設計的時(shí)候提供一個(gè)SQL查詢(xún)。在運行期,這個(gè)查詢(xún)將被執行以用來(lái)從數據庫中獲取要裝填的數據。在這種情況下,JasperReport僅需要一個(gè)java.sql.Connection對象來(lái)取代通常的數據對象。JasperReport需要這個(gè)連接對象來(lái)連接數據庫管理系統并執行查詢(xún)操作。
在查詢(xún)結束之后,JasperReport將自動(dòng)生成一個(gè)JRResultSetDataSource,并將它返回給報表裝填過(guò)程。
Class net.sf.jasper.engine.JRAbstractScriptlet
這個(gè)類(lèi)同樣用于報表裝填期間,用戶(hù)可以自己定義一些代碼,并由報表引擎在裝填過(guò)程中執行。這些用戶(hù)代碼可以處理報表數據操作,或在一些定義好的時(shí)刻執行,例如page,列,或組的分割處。
Class net.sf.jasper.engine.JRDefaultScriptlet
這是一個(gè)非常方便的JRAbstractScriptlet的子類(lèi)。通常情況下你應該選擇繼承這個(gè)類(lèi)。
Class net.sf.jasper.engine.JasperPrintManager
這個(gè)類(lèi)用戶(hù)提供打印方法,用戶(hù)可以將整個(gè)文檔或部分文檔傳遞給它,也可以選擇是否顯示打印Dialog,這在他的API文檔中可以找到,這里不再贅述。
Class net.sf.jasper.engine.JasperExportManager
顧名思義,這個(gè)類(lèi)負責文檔的導出。這個(gè)類(lèi)的具體信息詳見(jiàn)API文檔。非常明顯和清除,沒(méi)什么好解釋的,Just use it即可。
Class net.sf.jasper.engine.JasperRunManager
有時(shí),我們僅僅需要構造一個(gè)流行的文檔格式,例如PDF,或HTML,而不需要將裝填過(guò)程后生成的JasperPrint對象保存到硬盤(pán)或其他中間媒體上。這時(shí),可以使用這個(gè)類(lèi)來(lái)直接將裝填過(guò)程生成的文檔導出到所需的格式。
Class net.sf.jasper.view.JRViewer
這是一個(gè)基于Swing的應用程序,你可以將它視為一個(gè)獨立組件,用來(lái)進(jìn)行打印預覽。用戶(hù)可以繼承這個(gè)類(lèi),來(lái)構造滿(mǎn)足自身要求的預覽程序。
Class net.sf.jasper.view.JasperViewer
這個(gè)類(lèi)更像是使用JRViewer的教學(xué)組件,它演示了一個(gè)Swing應用程序如何裝在并顯示報表。
Class net.sf.jasper.view.JasperDesignViewer
這個(gè)類(lèi)用于報表的設計期間,用來(lái)預覽報表模版。它僅作為一個(gè)開(kāi)發(fā)工具存在于類(lèi)庫中。
Class net.sf.jasper.engine.util.JRLoader
裝載器用于報表生成的各個(gè)主要階段—編譯,裝填等等。用戶(hù)和引擎都可以利用這個(gè)類(lèi)來(lái)裝載所需的序列化對象如file,URLs,intput stream等等。這個(gè)類(lèi)最令人感興趣的函數當屬loadOnjectFromLocation(String location)。當用戶(hù)使用這個(gè)類(lèi)從指定地點(diǎn)裝載對象的時(shí)候,該函數將首先將location解釋為一個(gè)合法的URL,如果解析失敗,函數將認為所提供的location是硬盤(pán)上的一個(gè)文件名,并將試圖讀取它。如果在指定地點(diǎn)沒(méi)找到文件,它將通過(guò)classpath定位一個(gè)相應于該location的資源,所有努力失敗之后,將拋出異常。
3 主要的任務(wù)和過(guò)程
這一節我們將看到對你的XML報表設計進(jìn)行分析,編譯,裝填數據,預覽結果和導出到其他格式的過(guò)程。
3.1 XML解析
JasperReport使用SAX2.0 API對XML文件進(jìn)行解析。然而,這并不是必須的,用于可以在執行其自行決定使用哪一種XML解析器。
JasperReport使用org.xml.sax.helpers.XMLReaderFactory類(lèi)的createXMLReader()來(lái)獲得解析器實(shí)例。在這種情況下,就像在SAX2.0文檔中說(shuō)的那樣,在運行期,把Java系統屬性org.xml.sax.driver(這是屬性的key)的值(value)設定為SAX driver類(lèi)的全限定名是必要的。用戶(hù)可以通過(guò)兩種方法做到這一點(diǎn),我稍后將解釋全部?jì)煞N方法。如果你想使用不同的SAX2.0XML解析器,你需要指定相應的解析器類(lèi)的名字。
設置系統屬性的第一種方法是在你啟動(dòng)Java虛擬機的時(shí)候,在命令行使用-D開(kāi)關(guān):java –Dorg.xml.sax.driver=org.apache.serces.parsers.SAXParser mySAXApp sample.xml
在JasperReport提供的所有例子中,都采用ANT構建工具來(lái)執行不同的任務(wù)。我們通過(guò)使用內置的 task中的元素來(lái)提供這一系統屬性:

第二種設置系統屬性的方法是使用java.lang.System.setProperty(String key, String value)
System.setProperty(“org.xml.sax.driver”,” org.apache.xerces.parsers.SAXParser”);
jsp/compile.jsp和web-inf/class/servlets/CompileServlet.java文件提供了這方面的例子。
注:對于第二種方法,我要說(shuō)些題外話(huà)。有關(guān)于JVM的系統屬性(我們可以通過(guò)System.out.println(System.getProperty(“PropertyKey”)來(lái)查看),可以在運行期像上面說(shuō)所得那樣用System.setProperty(“propertyKey”,”propertyValue”);來(lái)進(jìn)行設置。但是一旦JVM已經(jīng)啟動(dòng)之后,其內建的系統屬性,如user.dir,就不能再被更改。奇怪的是我們仍可以用System.setProperty()方法對其進(jìn)行設置,而在用System.out.println(System.getProperty())方法進(jìn)行查看的時(shí)候發(fā)現,其值已經(jīng)更改為我們設置的值,但事實(shí)上我們設置的值不會(huì )起任何作用。所以對于內置的屬性,我們只能通過(guò)-D開(kāi)關(guān)在JVM執行之前進(jìn)行設置。對于org.xml.sax.driver,由于它不是系統內建屬性,所以仍然可以在JVM啟動(dòng)之后加以設置。更詳細的信息可以參考王森的〈Java深度歷險〉。
3.2 編譯報表設計(Report Designs)
為了深成一個(gè)報表,用戶(hù)需要首先生成報表的設計(report’s design),生成方法或采用直接編輯XML文件,或通過(guò)程序生成一個(gè)net.sf.jasper.engine.design.JasperDesign對象。本文中,我將主要采用編輯XML文件的方法,因為這種方法在目前是使用JasperReport類(lèi)庫的最好的方法,并且我們有機會(huì )更好的了解類(lèi)庫的行為。
先前提到過(guò),XML報表設計是JasperReport用來(lái)生成報表的初級材料(raw meterial)。這是因為XML中的內容需要被編譯并載入到JasperDesign對象中,這些對象將在報表引擎向其中填入數據之前經(jīng)過(guò)編譯過(guò)程。
注意:大多數時(shí)候,報表的編譯被劃歸為開(kāi)發(fā)時(shí)期的工作。你需要編譯你的應用程序報表設計,就像你編譯你的Java源文件一樣。在部署的時(shí)候,你必須將編譯好的報表,連同應用程序一起安裝到要部署的平臺上去。這是因為在大多數情況下報表設計都是靜態(tài)的,很少用應用程序需要提供給用戶(hù)在執行期編譯的,需要動(dòng)態(tài)生成的報表。
報表編譯過(guò)程的主要目的是生成并裝載含有所有報表表達式(report expression)的類(lèi)的字節碼。這個(gè)動(dòng)態(tài)生成的類(lèi)將會(huì )被用來(lái)在裝填數據,并給所有報表表達式求值(evaluate)的時(shí)候使用。具體例子是,如果你用IReport生成一個(gè)報表名字叫SimpleSheetTest,它的XML設計文件名叫SimpleSheetTest.jrxml,同時(shí)和它在同一目錄下IReport會(huì )自動(dòng)生成一個(gè)文件名為SimpleSheetTest.java,里面主要是一些報表元素,如Field,Parameters,Variables的定義,以及一些求值表達式。當然,像上面提到的,這個(gè)文件在你直接使用JasperReport API的時(shí)候是看不到的,因為它是在執行期生成的一個(gè)Class。要想看到它的辦法是:在IDE(JBuilder,Eclipse)中單步執行程序,在報表打印的階段,你將能跟蹤到這個(gè)類(lèi),它的名字就是“你的報表名.java”,按上面的例子就是SimpleSheetTest.java,這和IReport是一致的。當然也可以像下面說(shuō)的那樣,到生成這個(gè)類(lèi)的臨時(shí)目錄里找到它。
在這個(gè)類(lèi)生成過(guò)程之前,JasperReport引擎需要驗證報表設計的一致性(consistency),哪怕存在一處驗證檢查失敗都不會(huì )繼續運行下面的工作。在下面的章節,我將會(huì )展示報表設計驗證成功之后的狀況。
對于這個(gè)包含了所有報表表達式(report expressions)的類(lèi)的字節碼,我們至少需要關(guān)心三個(gè)方面的內容:
臨時(shí)工作目錄(temporary working directory)
Java 編譯器的使用
Classpath

為了能夠編譯Java源文件,這個(gè)文件必須被創(chuàng )建并且被保存到磁盤(pán)上。Java編譯過(guò)程的輸出是一個(gè).class文件,這個(gè)包含所有報表表達式的類(lèi)在這個(gè)工作目錄里被創(chuàng )建并編譯,這也是為什么JasperReport需要訪(fǎng)問(wèn)這個(gè)臨時(shí)目錄的原因。當報表的編譯過(guò)程結束之后,這些臨時(shí)的類(lèi)文件將被自動(dòng)刪除,而生成的字節碼將保存在net.sf.jasper.engine.JasperReport對象中。如果需要的話(huà),這個(gè)類(lèi)可以將自己序列化(serialized itself)并保存到磁盤(pán)上。這就是IReport的做法。
缺省情況下,這個(gè)臨時(shí)工作目錄就是啟動(dòng)JVM時(shí)的當前目錄,這卻取決于JVM的系統屬性user.dir。通過(guò)更改系統屬性jasper.report.compile.temp,用戶(hù)可以很容易更改這個(gè)工作目錄。在Web環(huán)境下,特別是當你不想讓含有啟動(dòng)Web Server的批處理文件的目錄和報表編譯過(guò)程的臨時(shí)工作目錄混在一起的時(shí)候,修改這個(gè)屬性就可以了。
上面提到的第二個(gè)方面涉及用來(lái)編譯報表表達式類(lèi)的Java編譯器。首先,報表引擎將試圖使用sun.tools.javac.Main類(lèi)來(lái)編譯Java源文件。這個(gè)類(lèi)包含在tools.jar中,當且僅當這個(gè)jar文件在JDK安裝目錄下的bin/目錄中,或在classpath中時(shí),sun.tools.javac.Main才能正常使用。
如果JasperReport不能成功裝載sun.tools.javac.Main文件,程序將動(dòng)態(tài)執行java編譯過(guò)程,就像我們通常用命令行那樣,使用JDK安裝目錄下的bin/目錄下的javac.exe。這就是為什么將JDK安裝目錄/lib/下的tools.jar文件copy到JasperReport工程的lib/目錄下是一個(gè)可選的操作(optional operation)。如果tools.jar不在classpath中,JasperReport將顯示錯誤信息并繼續上面提到的操作。
當編譯Java源文件的時(shí)候,最重要的事情莫過(guò)于classpath。如果Java編譯器不能在指定的classpath中找到它試圖編譯的所有相關(guān)類(lèi)的源文件,則整個(gè)過(guò)程將失敗并停止,錯誤信息將在控制臺顯示出來(lái)。同樣的事情也將發(fā)生在JasperReport試圖編譯報表表達式類(lèi)的時(shí)候。所以,在runtime為編譯過(guò)程提供正確的classpath是非常重要的。例如,我們我們需要確認在classpath中,我們提供了在報表表達式中可能用到的類(lèi)(custom class)。
在這個(gè)方面也有一個(gè)缺省的行為。如果沒(méi)有為編譯report class特殊指定classpath,引擎將會(huì )使用系統屬性java.class.path的值來(lái)確定當前的JVM classpath。如果你指定了系統屬性jasper.reports.compile.class.path的值,你可以用你定義的classpath來(lái)覆蓋缺省行為。
大多數情況下,編譯一個(gè)report只需要簡(jiǎn)單的調用JasperReport類(lèi)庫中的JasperCompileManager.compileReport(myXmlFileName);即可。調用之后將生成編譯好的report design并存儲在.jasper文件中,這個(gè)文件將會(huì )保存在和提供XML report design文件相同的目錄中。
3.3 Report Design 預覽
JasperReport類(lèi)庫并沒(méi)有提供高級的GUI工具來(lái)輔助進(jìn)行設計工作。但是目前已經(jīng)有至少4個(gè)project試圖提供這樣的工具。然而,JasperReport本身提供了一個(gè)很有用的可視化組件來(lái)幫助報表設計者在編譯的時(shí)候預覽報表設計(其實(shí)不如直接用IReport方便)。
net.sf.jasper.view.JasperDesigner是一個(gè)基于Swing的Java應用程序,它可以載入并顯示XML形式或編譯后的報表設計。盡管它不是一個(gè)復雜的GUI應用程序,缺乏像拖拽可視化報表元素這樣的高級功能,但是它仍然是一個(gè)有用的工具(instrument)。所有JasperReport工程提供的例子都利用了這個(gè)報表查看器(report viewer)。
如果你已經(jīng)安裝了ANT(別告訴我你不知道什么是ANT),想要查看一個(gè)簡(jiǎn)單的報表設計(JasperReport工程所帶例子),你只需要到相應的文件夾下輸入如下命令:
〉ant viewDesignXML 或者 〉ant viewDesign
如果你沒(méi)安裝ANT,要達到上面的效果就不是很容易,因為JasperReport本身需要一些其他輔助的jar包(在JasperReport安裝目錄/lib下),在運行的時(shí)候,你需要把這些jar包都包含到你的classpath里面,并且正確設計系統屬性,如上面提到的org.xml.sax.driver。我可以展示一下在windows下的例子:
>java -classpath ./;../../../lib/coMMons-digester.jar;
../../../lib/commons-beanutils.jar;../../../lib/commons-collections.jar;
../../../lib/xerces.jar;../../../lib/jasperreports.jar
-Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser
dori.jasper.view.JasperDesignViewer -XML -FFirstJasper.xml
很麻煩吧?還是趕快弄個(gè)ANT吧。下面是預覽之后的結果(其實(shí)用IReport更好)

3.4報表裝填(Filling Report)
報表裝填(report filling)過(guò)程是JasperReport library最重要的功能。它體現了這個(gè)軟件最主要的目的(main objective),因為這一過(guò)程可以自由的操作數據集(data set),以便可以產(chǎn)生高質(zhì)量的文檔。有3種材料需要裝填過(guò)程中作為輸入提供給JasperReport:
report design(report templet)
參數(parameters)
數據源(data source)
這一過(guò)程的輸出通常是一個(gè)單一的最終要被查看,打印或導出到其他格式的文檔。
要進(jìn)行這一過(guò)程,我們需要采用net.sf.jasper.engine.JasperFillManager類(lèi)。這個(gè)類(lèi)提供了一些方法來(lái)讓我們裝填報表設計(report design),report design的來(lái)源可以是本地磁盤(pán),輸入流,或者直接就是一個(gè)已存在于內存中的net.sf.jasper.engine.JasperReport類(lèi)。輸出的產(chǎn)生是于輸入類(lèi)型相對應的,也就是說(shuō),如果JasperFillManager接到一個(gè)report design的文件名,裝填結束后生成的report將會(huì )是一個(gè)放在磁盤(pán)上的文件;如果JasperFillManager收到的是一個(gè)輸入流,則生成的report將會(huì )被寫(xiě)道一個(gè)輸出流中。
有些時(shí)候,這些JasperFillManager提供的方法不能滿(mǎn)足某些特定的應用的要求,例如可能有人希望他的report design被作為從classpath中得到的資源,并且輸出的報表作為一個(gè)文件存放在一個(gè)指定的磁盤(pán)目錄下。遇到這種情況時(shí),開(kāi)發(fā)人員需要考慮在將報表設計傳遞給報表裝填過(guò)程之前,用net.sf.jasper.engine.util.JRLoader類(lèi)來(lái)裝載report design對象。這樣,他們就能獲得像報表名這樣的report design屬性,于是開(kāi)發(fā)者就能生成最終文檔的名字(construct the name of the resulting document),并將它存放到所需的位置上。
在現實(shí)中,有許多報表裝填的情境(scenarios),而裝填管理器僅試圖覆蓋其中最常被使用到的部分。然而對于想要自己定制裝填過(guò)程的人來(lái)說(shuō),只要采用上面所說(shuō)的方法,任何開(kāi)發(fā)者都可以達到滿(mǎn)意的結果。
報表參數通常作為java.util.Map的value提供給裝填管理器,參數名為其鍵值(key)。
作為裝填過(guò)程所需的第三種資源—數據源,有如下兩種情況:
通常,引擎需要處理net.sf.jasper.engine.JRDataSource接口的一個(gè)實(shí)例,通過(guò)這個(gè)實(shí)例,引擎可以在裝填過(guò)程中獲取所需數據。JasperFillManager提供的方法支持所有的JRDataSource對象(這是一個(gè)Interface,上面一章提到過(guò)它的常用實(shí)現)。
然而,這個(gè)管理器還提供一些接受java.sql.Connection對象作為參數的方法集,來(lái)取代所需的數據源對象。這是因為在很多情況下,報表生成所需的數據都來(lái)源于某個(gè)關(guān)系型數據庫中的表(table)。
在報表中,用戶(hù)可以提供SQL查詢(xún)語(yǔ)句來(lái)從數據庫中取回報表數據(report data)。在執行期,engine唯一需要做的是獲得JDBC connection對象,并使用它來(lái)連接想要連接的數據庫,執行SQL查詢(xún)并取回報表數據。在后臺,引擎將使用一個(gè)特殊的JRDataSource對象,但是它對于調用它的程序來(lái)說(shuō)是透明的。
JasperReport工程提供了相關(guān)的例子,它們采用HSQL數據庫服務(wù)器(在工程文件中,有一個(gè)相應的文件夾),要運行這些例子你需要首先啟動(dòng)該服務(wù)器,方法是:在/demo/hsqldb目錄下輸入如下命令:>ant 或者 >ant runServer
沒(méi)裝ANT就麻煩點(diǎn):>java -classpath ./;../../lib/hsqldb.jar org.hsqldb.Server
一下代碼片斷顯示了query例子是如何裝填數據的:
//Preparing parameters
Map parameters = new HashMap();
parameters.put("ReportTitle", "Address Report");
parameters.put("FilterClause", "‘Boston‘, ‘Chicago‘, ‘Oslo‘");
parameters.put("OrderClause", "City");
//Invoking the filling process
JasperFillManager.fillReportToFile(fileName, parameters, getConnection());
3.5 查看報表(Viewing Reports)
報表填充階段的輸出通常是一個(gè)JasperPrint對象,如果把它保存在磁盤(pán)上,通常以一個(gè).jrprint文件的形式存在。JasperReport擁有一個(gè)內置的查看器,用來(lái)查看用內置的XML導出器(XML exporter)獲得的XML格式的報表文件。這個(gè)查看器就是以前提到過(guò)的net.sf.jasper.niew.JRViewer—一個(gè)基于Swing的應用程序組件,用戶(hù)可以通過(guò)繼承這個(gè)類(lèi)來(lái)定制自己所需的查看器。JasperReport工程中自帶的例子webapp中,你可以閱讀JRViewerPlus類(lèi)的代碼來(lái)獲取進(jìn)一步內容。
注意:JasperViewer更像是一個(gè)教人們如何使用JRViewer組件的演示程序,這里要注意一點(diǎn),當你調用JasperViewer的viewReport()方法來(lái)顯示報表時(shí),如果你關(guān)閉了預覽Frame,整個(gè)應用程序將會(huì )隨之結束,因為這個(gè)函數最后調用了System.exit(0);你可以通過(guò)繼承這個(gè)類(lèi),并重新在你的Viewer里注冊java.awt.event.WindowListener來(lái)避免這一情況的發(fā)生。
3.6 打印報表
JasperReport類(lèi)庫的主要目標,就是生成可打印的文檔。而且多數應用程序生成的報表都是需要落實(shí)(或打?。┑郊垙埳?。我們可以用net.sf.jasper.engine.JasperPrintManager來(lái)打印JasperReport生成的文檔。當然,報表也同樣可以在被導出到其他格式如PDF,HTML之后再被打印。通過(guò)JasperPrintManager提供的方法,我們可以打印整個(gè)文檔,打印單個(gè)文檔或打印某一范圍內的文檔,可以顯示打印對話(huà)框也可以不顯示。下面的例子演示了不顯示對話(huà)框,打印整個(gè)文檔的方法:JasperPrintManager.printReport(myReport,false);
這個(gè)例子顯示了如何打印5-11頁(yè)的文檔,同時(shí)顯示打印對話(huà)框:net.sf.jasper.engine.JasperPrintManager.printPages(myReport,4,10,true);
3.7 導出報表
在一些應用程序環(huán)境下,將JasperReport生成的文檔從其特有的格式導出到其他更為流行的格式如PDF,HTML是非常有用的。這樣一來(lái),其他人就可以在沒(méi)有安裝JasperReport的情況下查看這些報表,特別是當這些文檔要通過(guò)網(wǎng)絡(luò )發(fā)送出去的時(shí)候。
JasperReport提供了JasperExportManager類(lèi)來(lái)支持此項功能。這項功能將會(huì )在以后不斷加入對新的格式的支持。目前,JasperReport主要支持導出PDF,HTML和XML類(lèi)型的文檔,下面是導出的代碼片斷:JasperExportManager.exortReportToHtmlFile(myReport);
注意:想要將自己的報表導出到其他格式的用戶(hù),需要實(shí)現JRExporter的接口,或繼承相應的JRAbstractExporter類(lèi)。
3.8 對象的載入和保存
當使用JasperReport的時(shí)候,你經(jīng)常會(huì )與序列化的對象,如以編譯的報表設計,或已生成的報表打交道。有時(shí),你需要手動(dòng)載入從不同的source如input stream或你用類(lèi)庫核心功能(lib’s core functionality)產(chǎn)生的序列化類(lèi)。JasperReport提供了兩個(gè)特殊的工具類(lèi)來(lái)提供上述操作的能力,這些類(lèi)通常供報表引擎自己使用:
net.sf.jasper.engine.util.JRLoader
net.sf.jasper.engine.util.JRSaver
第一個(gè)類(lèi)提供了一些方法讓我們能夠從不同類(lèi)型的數據源如文件,URL,input stream和classpath里面獲取序列化對象。最令人感興趣的方法是loadObjectFormLocation(String)。它已經(jīng)在上一章中介紹過(guò)了,這里不再贅述。
與上面的對象載入工具相反的部分是JRSaver類(lèi),它可以幫助程序員將自己的類(lèi)序列化之后存放到本地磁盤(pán)或通過(guò)Output Stream發(fā)送到網(wǎng)絡(luò )上去。
有時(shí),開(kāi)發(fā)人員可能想要載入已經(jīng)生成好的report,或最終的已經(jīng)被導出到XML格式的JasperReport文檔,這與上面所說(shuō)的直接load序列化對象有所不同。這時(shí),我們需要載入的是將載入的XML內容進(jìn)行編譯,并生成JasperPrint對象,而并非僅僅是載入序列化對象。這時(shí),我們可以通過(guò)net.sf.jasper.engine.xml.JRPrintXmlLoader類(lèi)的一些靜態(tài)方法,通過(guò)編譯從XML文件中讀取的內容構建出一個(gè)位于內存中的文檔對象。
4 報表設計(Report Designs)
報表設計體現了一個(gè)模版,JasperReport引擎利用這個(gè)模版將同臺生成的內容傳遞給打印機,屏幕或Web。存儲在數據庫中的數據在報表裝填的過(guò)程過(guò)被組織起來(lái),根據已有的報表設計來(lái)獲得可以進(jìn)行打印的,面向頁(yè)面的(page oriented)文檔。
總而言之,一個(gè)報表設計包含了所有的結構相關(guān)信息和將數據提供給報表所涉及的各個(gè)方面。這些信息涉及將在文檔中顯示出來(lái)的各種text或圖像元素的位置和內容,自定義計算(custom calculation),數據組織,報表生成時(shí)的數據操作,等等。
報表設計通常都定義在一個(gè)擁有特殊格式的XML文檔中,并且在被填充數據之前要經(jīng)歷JasperReport的編譯過(guò)程,有關(guān)于這個(gè)XML文檔的詳細信息我們將在以后說(shuō)明。然而JasperReport也允許用戶(hù)通過(guò)JasperReport提供的API構造in-memory報表對象,例程noxmldesign就是很好的例子,但是我們通常不這么用。
4.1 DTD Reference
當使用XML文件進(jìn)行報表設計的時(shí)候,JasperReport將使用內置的DTD文件來(lái)驗證其受到的XML內容的有效性。如果XML驗證通過(guò),則說(shuō)明所提供的報表設計符合JasperReport所需要的XML結構和語(yǔ)法規則,其引擎能夠生成經(jīng)過(guò)編譯的report design。
有效的XML文檔總是在驗證時(shí)指向JasperReport的內部DTD文件。如果沒(méi)有提供DTD文檔的引用,報表的編譯過(guò)程將會(huì )突然結束。這對所有人來(lái)說(shuō)都是一個(gè)負擔,因為DTD引用通常是相同的,并且這些引用可能會(huì )簡(jiǎn)單的被從以前的報表設計中copy過(guò)來(lái)。在一開(kāi)始,你需要將這個(gè)引用從給定的例子中copy過(guò)來(lái)。
正如以前說(shuō)的一樣,報表引擎僅能識別指向其內部DTD文件的的引用。你不能隨便從類(lèi)庫的源文件中將那些DTD文件copy到別的地方,再在你的報表設計文件中文件中指向你copy的那些DTD文件。如果你想那樣做的話(huà),你將需要調整類(lèi)庫中某些類(lèi),包括net.sf.jasper.engine.xml.JRXmlDigester類(lèi)的某些代碼。如果你遇到像引擎無(wú)法找到其內部的DTD文件而導致的無(wú)法載入資源的問(wèn)題,請確定你已經(jīng)在使用外部DTD文件之前排除了所有可能發(fā)生的情況。遇到這樣的問(wèn)題是不太可能的,因為資源載入機制會(huì )隨著(zhù)時(shí)間不斷改進(jìn)。JasperReport只有兩種合法的XML報表設計的DTD引用,他們是:
或者

XML報表的root元素是,下面是一個(gè)普通帶JasperReport的樣子:





4.2 XML 編碼
當要生成不同語(yǔ)言的XML報表設計的時(shí)候,在XMl文件的首部的編碼屬性需要特別關(guān)注一下。缺省情況下,如果這個(gè)屬性的值沒(méi)被訂制,則XML解析器將會(huì )使用“UTF-8”作為XML文件的編碼格式。這一點(diǎn)是非常重要的,因為報表設計通常包含了靜態(tài)的本地化text。對于大多數西歐語(yǔ)言來(lái)說(shuō),ISO-8859-1編碼,也就是我們常說(shuō)的LATIN1將會(huì )很好的處理如法語(yǔ)中重音符號的顯示問(wèn)題。

在編輯XML文件的時(shí)候,要找到某種特殊語(yǔ)言的編碼類(lèi)型,你可以查看XML document.FIXME
4.3 報表屬性
我們上面已經(jīng)看到,斯XML報表設計的根元素。這一節我將介紹報表設計對象的Property的細節以及這些屬性所對應的XML attributes(為避免混淆,我將不提供Property和Attribute的中文而直接使用英文)。

Report Name
每一個(gè)報表都必須有一個(gè)名字。這個(gè)名字是相當重要的,因為類(lèi)庫需要它來(lái)生成文件,尤其是當編譯,裝填,導出報表的默認行為被使用的時(shí)候,這個(gè)名的作用更為重要。這個(gè)名字是以元素的name attribute的形式提供的,并且是強制必須填寫(xiě)。
Column Count(列數)
JasperReport允許生成每頁(yè)的列數超過(guò)一列的報表,正如下面的圖片,展示了擁有兩列的報表:

默認情況下,報表引擎生成每頁(yè)一列的報表。
Print Order(打印順序)
對于擁有超過(guò)一列的報表,為其提供列將被以什么順序填充是很重要的。你可以使用的printOrder attribute來(lái)進(jìn)行設置。有如下兩種情況:
Vertical Filling:這個(gè)選項將導致列是自頂向下被填充(printOrder=”Vertical”)
Horzontal:列將自左向右被填充(printOrder=”Horizontal”)
缺省設置將是printOrder=Vertical
Page Size(頁(yè)面大?。?br>有兩個(gè)attribute是用來(lái)提供要生成的文檔大小的:pageWith,pageHeight。像所有其他顯示元素位置和尺寸的attribute一樣,這兩個(gè)attribute是以像素為單位的。JasperReport采用Java默認的每英寸72點(diǎn)的設置。這意味著(zhù)pageWith=”595”將大約是8.26英寸,這大概是A4紙的尺寸。
默認的紙張大小是A4紙:pageWith=”595” pageHeight=”842”
Page Orientation(默認設置為Portrait)
orientation屬性用來(lái)設置文檔打印格式是“Portrait”還是“Landscape”。JasperReport允許用戶(hù)在從“Portrait”切換到“Landscape”的時(shí)候調整液面的寬度和高度。我們先看一個(gè)例子:我們假定要生成一個(gè)A4紙的報表,采用“Protrait”格式。
pageWidth=”595” pageHeight=”842” orientation=”Portrait”
如果我們決定用A4紙的“Landscape”布局,首先要調整相應的頁(yè)面寬度和高度:
pageWidth=”842” pageHeight=”595” orientation=”Landscape”
這是因為JasperReport需要確切知道它所要繪制的報表頁(yè)的寬度和高度,而不只看我們提供的orientation屬性,至少在報表裝填的時(shí)候是這樣。orientation屬性?xún)H在報表打印時(shí)有用,來(lái)通知打印機或某些exporters頁(yè)面的orientation設置。
Page Margins(頁(yè)邊距)
一旦頁(yè)面大小確定下來(lái),用戶(hù)就可以在生成報表的時(shí)候設定報表的邊距。有四個(gè)屬性來(lái)完成這項工作:topMargin,LeftMargin,bottomMargin和rightMargin。缺省的設置是上下邊距20像素,左右邊距20像素。
Column Size and Spacing(列寬和列間距)
一個(gè)報表可能含有多列,我們可以通過(guò)上面提到的columnCount屬性得到報表列數。JasperReport需要知道列的寬度和列間距的大小。有兩個(gè)屬性用于這項工作:columnWidth和columnSpacing。當我們對報表設計進(jìn)行編譯的時(shí)候,編譯器會(huì )對這項設置進(jìn)行有效性檢查(validation check)--看列的寬度和列間距是否符合給定的頁(yè)面寬度和頁(yè)邊距。因為缺省的列數為一,所以缺省的列間距為0像素,并且缺省的列寬等于頁(yè)面寬度減去左右邊距所得的值。在上面A4的例子中,列寬即為555像素。
Empty Data Source Behavior
有時(shí)我們提供給我們的報表的數據源可能會(huì )沒(méi)有任何record。whenNoDataType屬性可以讓你選擇當所提供的數據源中沒(méi)有數據的時(shí)候入和察看生成的報表。如下有三種不同的可能性,你可以任選其一:
Empty Document:生成的報表不含有頁(yè)面(no page in it)。當你試圖裝載這樣的文檔(whenNoDataType=”NoPages”)的時(shí)候,Viewer 可能會(huì )拋出一個(gè)錯誤。
Blank page:表示生成的報表將僅含有一個(gè)空白頁(yè)。(whenNoDataType=”BlankPage”)
All sections displayed:除了detail部分的其他部分將在生成的文檔中顯示出來(lái)。(whenNoDataType=”AllSectionNoDetail”)。
缺省的設置是whenNoDataType=”NoPages”。
Title and Summary Sections Placement(標題和摘要的放置)
如果你想讓title部分和summary部分在單獨的一頁(yè)里顯示,你所需要做的事情就是讓下面的一個(gè)或兩個(gè)屬性的值為“true”:isTitleNewPage,isSummaryNewPage。這兩個(gè)屬性缺省情況下為false。
注意:即使你選擇了在最后一頁(yè)的剩余部分顯示summary,如果列數超過(guò)一列,并且第二列已經(jīng)在最后一頁(yè)出現的時(shí)候(沒(méi)試過(guò),等有機會(huì )試驗一下),新的一頁(yè)將會(huì )被自動(dòng)生成。
Scriptlet Class
scirptletClass屬性用于設置用于當前報表的scriptlet類(lèi)的名字。在以后我會(huì )對Scriptlet進(jìn)行詳細討論。如果你沒(méi)為這個(gè)屬性提供任何值,報表引擎將會(huì )使用net.sf.jasper.engine.JRDefaultScriptlet的實(shí)例。
5 報表數據(Report Date)
當我們談到報表裝填過(guò)程的時(shí)候,有三樣東西需要作為輸入提供給報表引擎:報表設計(report design),參數值(parameter values)和報表的數據源(data source)。
在先前的章節,我們已經(jīng)看到了有關(guān)報表設計的某些方面,現在我們要更加詳細的關(guān)注其他兩方面的內容:參數(parameter)和報表數據源。他們描繪了報表引擎在裝填報表過(guò)程中所用到的僅有的數據來(lái)源。像你用其他報表工具所希望的一樣,這些數據將會(huì )根據報表設計中的定義的模版(template)被組織起來(lái),并被用來(lái)生成準備打印的、面向頁(yè)面的文檔。
5.1 表達式(expressions)
表達式是JasperReport的一個(gè)非常有用的特性。他們可以用來(lái)聲明執行各種執行各種計算(calculations)的報表變量(report variables),進(jìn)行報表的數據組織,定制報表文本字段(text field)的內容或者進(jìn)一步定制報表對象的appearance。
所有報表表達式基本上都是Java表達式,他們可以以特殊的語(yǔ)法引用報表參數(parameter),報表字段(field)和報表變量(variable)。在XML報表設計中,有一些用于定義表達式的元素:,,,,,等等
因為所有的JasperReport表達式都是真正(real)的Java表達式,只要你用完整的類(lèi)名(包括包名)來(lái)引用這些表達式,你就可以在任何class中使用他們。當你編譯報表和裝填數據的時(shí)候,你應該確定你在報表表達式中使用的類(lèi)已經(jīng)寫(xiě)入了classpath。
報表參數引用是通過(guò)$P{}序列引入的,例如:

$P{ReportTitle}

這個(gè)例子假定我們在報表設計中有一個(gè)名為ReportTitle的報表參數,這個(gè)參數是一個(gè)java.lang.String類(lèi)。當報表進(jìn)行裝填的時(shí)候,文本字段將會(huì )顯示這個(gè)參數的值。
為了在一個(gè)表達式中使用報表字段,字段名必須放在$F{}的括號中。例如,如果我們想要在一個(gè)文本字段中顯示兩個(gè)數據源字段的連接值(concatenated values),我們可以定義如下表達式:

$F{FirstName} + “ “ + $F{LastName}

表達式可以更加復雜:

$F{FirstName} + “ “ + $F{LastName} + “ was hired on “ +
(new SimpleDateFormat(“MM/DD/YYYY”)).format($F{HireDate)) + “.”

正如你所看到的一樣,參數、字段和變量引用都是通過(guò)用JasperReport的特殊語(yǔ)法從一個(gè)真正地Java對象中引入的。(實(shí)際上是一個(gè)JREvaluator對象,該對象是在運行其生成的動(dòng)態(tài)對象,并不能在本地磁盤(pán)上見(jiàn)到它的身影,不過(guò)如果你使用iReport的話(huà),你就可以在生成報表文件的同一目錄下看到它的本來(lái)面目)
5.2 參數(Parameters)
Parameters是傳遞給報表裝填操作的對象引用。這些參數主要作用于把那些不能從報表數據源中獲得的數據傳給報表引擎。例如,我們可能要把執行報表裝填過(guò)程的用戶(hù)名字專(zhuān)遞給報表引擎,如果我們想讓它顯示在報表上或者在我們想在報表的title上動(dòng)態(tài)的改變它,我們就可以以參數的形式傳給報表引擎。

我們可以用如下的方式定義參數:



這里所提供的報表參數值可以被用到各種報表表達式中,在報表SQL查詢(xún)中,甚至可以用到報表的scriptlet類(lèi)里。下面是構成參數定義的全部組件(XML元素):
參數名
name屬性是一個(gè)強制屬性。JasperReport的命名習慣和Java語(yǔ)言的命名習慣是類(lèi)似的,這意味著(zhù)參數名應該是一個(gè)單詞,其中不含特殊字符(如分號)。
參數類(lèi)型
報表參數的第二個(gè)強制屬性是提供參數值的類(lèi)型名。這個(gè)類(lèi)型屬性可以使任意的值,只要這個(gè)類(lèi)型的名字在報表編譯期和裝填期能在classpath中找到即可。
Prompting for Parameter values
在GUI引用程序中,建立一個(gè)報表參數集,讓用戶(hù)在執行裝填過(guò)程之前輸入某些應用程序需要用戶(hù)輸入的報表參數是很有用的??蛇x參數isForPropting參數用來(lái)聲明是否顯示提示信息讓用戶(hù)輸入某些參數。下面的例子中,我聲明了一個(gè)文本參數,當需要用戶(hù)輸入參數值的時(shí)候,這個(gè)文本參數用來(lái)在一個(gè)已定制的對話(huà)框中描述需要用戶(hù)輸入什么樣的參數。


Please type here the report comments if any
]]>


注意:相信大家都知道表示“內容”將不被XML解析器解析,也就是說(shuō),你可以在“內容”里加入XML的特殊字符,如>,<等等。
參數的默認值(parameter default value)
通常參數值都是使用java.util.Map對象傳給裝填過(guò)程的,其中參數名作為Key。這樣,你就不用每次都為每個(gè)參數提供一個(gè)value了—可以批量放到Map對象里一起傳給裝填管理器。如果你沒(méi)有為參數提供一個(gè)value,引擎就認為它是null。但是如果你為它提供了一個(gè)默認值,則引擎將在你沒(méi)提供這個(gè)參數值的情況下使用這個(gè)默認值。如果你在裝填時(shí)沒(méi)提供數據,下面的java.util.Date將在裝填是被引擎使用來(lái)表示當天日期:


new java.util.Date()


在參數的默認表達式中,我們可以使用這個(gè)與定義的報表參數。
5.2.1 內置的報表參數
每一個(gè)報表設計中都含有一些與定義的報表參數,這些內置的參數的描述如下:
REPORT_PARAMETERS_MAP
這是一個(gè)內置的參數,這個(gè)參數總是指向一個(gè)java.util.Map對象,該對象保存了用戶(hù)調用報表裝填過(guò)程時(shí)傳遞給報表引擎的用戶(hù)定的參數。
REPORT_CONNECTION
這個(gè)報表參數指向一個(gè)java.sql.Connection對象,這個(gè)對象被提供給報表引擎用來(lái)通過(guò)JDBC來(lái)執行SQL報表查詢(xún)。將master報表使用的JDBC Connection對象傳遞給subreport是非常有用的,有關(guān)這方面信息請查看subreport例子
REPORT_DATASOURCE
在報表裝填的時(shí)候,我們可以或者直接由應用程序中提供,或由報表引擎從所提供的JDBC Connection在后臺create而獲得一個(gè)數據源。這個(gè)內置的參數允許我們在報表表達式中或scriptlet中訪(fǎng)問(wèn)報表數據源,而不論我們?yōu)槭裁匆@么做。
REPORT_SCRIPTLET
即使報表不使用scriptlet,這個(gè)內置的參數仍將指向一個(gè)net.sf.jasper.engine.JRAbstracStriptlet實(shí)例,該實(shí)例實(shí)際是一個(gè)net.sf.jasper.engine.JRDefaultScriptlet對象。
但是當使用scriptlet時(shí),報表裝填過(guò)程所生成的這個(gè)指向scriptlet類(lèi)實(shí)例的引用允許我們調用其中的某些特殊函數,使用或控制scriptlet對象在裝填過(guò)程中已經(jīng)準備好的數據。在scriptlet例子中你可以看到更詳細的使用過(guò)程。
5.3 Data Source(數據源)
在進(jìn)行報表裝填的時(shí)候,JasperReport引擎迭代的從用戶(hù)提供的數據源中提取record,并根據報表設計所提供的模版生成報表的各個(gè)部分(section)。通常情況下,引擎需要接收一個(gè)net.sf.jasper.engine.JRDataSource對象作為報表數據源。但是像我們即將看到的那樣,當報表數據存儲于關(guān)系型數據庫的時(shí)候,JasperReport有了讓用戶(hù)提供一個(gè)JDBC鏈接對象來(lái)替代通常的數據源對象的特性。JRDataSource接口非常簡(jiǎn)單,如果我們想要實(shí)現它只需要實(shí)現下面兩個(gè)方法:
public Boolean next() throw JRException;
public Object getFieldValue(JRField jrField) throw JRException
在報表裝填的時(shí)候,next()方法將被報表引擎調用,迭代的從數據源中獲取數據。第二個(gè)方法用來(lái)為每個(gè)在當前數據源記錄(data source record)中的報表字段(report field)提供value。
應當知道,從數據源取得數據的唯一方法是使用report field。一個(gè)數據源對象更像是一個(gè)二維表,表中含有數據。這個(gè)二維表的行是一條一條的record,而每一列都映射為一個(gè)report field。所以我們可以在report表達式中使用數據源。JasperReport提供了一些缺省的JRDataSource實(shí)現,我們來(lái)具體看一下:
Class net.sf.jasper.engine.JRResultSetDataSource
這是一個(gè)非常有用的缺省實(shí)現,因為他外覆(wrap)了java.sql.ResultSet對象。由于多數報表的生成都采用關(guān)系數據庫中存儲的數據,所以這個(gè)類(lèi)是被使用得最為廣泛的數據源對象。然而在以下的兩種情況下您可以不必在裝填過(guò)程中自己生成這個(gè)對象:
如果你選擇在你的報表中用SQL查詢(xún)來(lái)獲得在關(guān)系數據庫的某個(gè)table中的數據,報表引擎將會(huì )通過(guò)執行給定的SQL查詢(xún)并且將返回的java.sql.ResultSet外覆為一個(gè)net.sf.jasper.engine.JRResultSetDataSource實(shí)例來(lái)執行這項操作。引擎唯一需要的是一個(gè)java.sql.Connection對象來(lái)執行查詢(xún)操作。這時(shí)你可以提供connection對象來(lái)作為通用數據源對象(usual data source object)。例子有:jasper,scriptlet,subreport和query。
當然你可以在應用程序中即JasperReport之外執行SQL查詢(xún)。這樣的話(huà),你可以手動(dòng)的外覆java.sql.ResultSet,再調用報表裝填過(guò)程之前實(shí)例化這個(gè)數據源對象。當使用這種類(lèi)型的數據源的時(shí)候,你需要為在result set中的每一列生命一個(gè)report field。report field的名字和類(lèi)型必須和列的名字和類(lèi)型匹配。
Class net.sf.jasper.engine.JREcptyDataSource
這個(gè)類(lèi)主要用于當生成報表的數據不是來(lái)自數據源,而是來(lái)自參數或重要的僅是數據源中virtual records的數量的時(shí)候。例子fonts,images,shapes和unicode都使用了這個(gè)類(lèi)來(lái)裝填報表,來(lái)模擬數據源中沒(méi)有一條記錄,所有字段都為null的情況。
Class net.sf.jasper.engine.data.JRTableModelDataSource
這個(gè)JRDataSource接口的缺省實(shí)現外覆了javax.swing.table.TableModel對象,它可以用在Java Swing應用程序中從已經(jīng)顯示到屏幕上的table中得數據來(lái)生成報表。--我喜歡。
通常有兩種方法來(lái)使用這種數據源:
通常,為了要從中取得數據,你需要為javax.swing.table.TableModel對象的每一列生命一個(gè)report field。但是有些情況下會(huì )出現問(wèn)題,比如report field的命名需要遵照Java命名規范來(lái)聲明變量,而table的列名則不需要。幸運的是,你仍然可以通過(guò)列的索引而不是它的名字來(lái)將report field與列進(jìn)行映射。例如,一個(gè)列名為“Produce Description”不可能被映射到名為“Produce Description”的report field上,因為report field名中含有空格,這將引起一個(gè)編譯錯誤。但是如果你知道這個(gè)列示table model對象的第三列(index=2),那么你就可以命名相應的字段“COLUMN_2”并無(wú)誤地使用這一列的數據。例子有:datasource
Class net.sf.jasper.engine.data.JRBeanArrayDataSource
這個(gè)類(lèi)外覆了一個(gè)JavaBeans數組,并且通過(guò)反射來(lái)獲取report field的值。在這種數據源中,一個(gè)JavaBean對象描述了一條記錄。如果我們有一個(gè)名為“ProductDescription”的report field,在獲取這個(gè)字段的值的時(shí)候,程序將會(huì )試圖通過(guò)反射機制調用一個(gè)當前JavaBeans對象中]名為getProductDescription()的方法。對于boolean字段,當調用get前綴的屬性不能返回其屬性值的時(shí)候,程序將會(huì )試圖使用is前綴的方法來(lái)獲得屬性值。
Class net.sf.jasper.engine.data.JRBeanCollectionDataSource
這個(gè)類(lèi)和上一個(gè)類(lèi)非常類(lèi)似,它也是使用反射機制和JavaBean命名規范,但是它外覆了一個(gè)java.util.Collection對象而不是一個(gè)JavaBean對象數組。在datasource例子中你可以看到進(jìn)一步的用法。
5.4 報表查詢(xún)(Report Query)
為了要為報表裝填數據,我們需要為報表引擎提供所需的數據,或者至少告訴它怎樣去獲取數據。JasperReport通常需要接受一個(gè)net.sf.jasper.engine.JRDataSource對象作為報表的數據源,同時(shí)作為更為強大的功能,JasperReport能直接用JDBC從關(guān)系數據庫總獲取數據。類(lèi)庫允許用戶(hù)在他們的報表設計中提供SQL查詢(xún)以便可以自運行期從數據庫中提取數據。要做到這一點(diǎn),你只需要在裝填的時(shí)候為裝填管理器的fillReport()方法提供一個(gè)java.sql.Connection而不是JRDataSource對象即可。
在報表中,可以使用元素來(lái)引入查詢(xún)。如果這個(gè)元素存在,則出現在報表參數聲明之后,報表field之前。

如下是一個(gè)SQL查詢(xún)的例子:

為了更好的定制從數據庫中取回的數據集(data set),一個(gè)重要的方面是在報表查詢(xún)字符串中報表參數的使用(use of report parameters)。在查詢(xún)中,這些參數可能會(huì )像動(dòng)態(tài)過(guò)濾器(dynamic filter)一樣工作,它們用特殊的語(yǔ)法被引入進(jìn)來(lái)為報表提供數據,很像report expression。
如下有兩種在查詢(xún)中的使用參數的方法:
1. 像通常的java.sql.PreparedStatement的參數那樣使用,用如下語(yǔ)法:

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

2. 有時(shí),我們需要使用參數來(lái)動(dòng)態(tài)更改SQL查詢(xún)的某些部分,或將整個(gè)SQL查詢(xún)作為參數提供給裝填過(guò)程。在這種情況下,語(yǔ)法稍微有些不同,向下面的例子,注意“!”

SELECT * FROM $P!{MyTable} ORDER BY $P!{OrderByClause}
]]>

在這個(gè)例子中,這個(gè)引入了參數值得特殊的語(yǔ)法確定了我們?yōu)檫@些參數所提供的值將會(huì )替代查詢(xún)中的參數引用($P!{}的內容)。這些參數將被傳給使用java.sql.PrepqredStatement對象的數據庫服務(wù)器。
事實(shí)上,報表引擎首先處理$P!{}參數引用,通過(guò)使用他們的值來(lái)獲取最重的SQL查詢(xún),并且僅當這件事完成之后,引擎才會(huì )將剩下的普通的$P{}參數引用傳遞給usual IN parameters。--實(shí)際上就是嵌套查詢(xún)啦。
第二種用于SQL查詢(xún)的參數引用允許你在運行期傳遞整個(gè)SQL查詢(xún)語(yǔ)句:
$P!{MySQLQuery}
注意:你不能在參數值中再加入參數引用,也就是說(shuō),參數引用不能嵌套使用。
更詳細的信息可以參看工程所帶的例程:jasper,subreport,scriptlet,webapp以及最有學(xué)習價(jià)值的query

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
JasperReports+iReport在eclipse中的使用
JasperReport查看和打印報告
使用JasperReport和iReport制作java報表
iReport專(zhuān)題學(xué)習之子報表(SubReport) 07
Java開(kāi)源報表JasperReport、iReport4.5.1使用詳解(三)
使用JasperReport+iReport進(jìn)行WEB開(kāi)發(fā)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久