- JavaWeb從入門到精通(視頻實戰版)
- 常倬林等編著
- 2094字
- 2018-12-31 19:36:07
6.8 在Struts中使用JasperReports
JasperReports(簡稱JR)是目前應用廣泛并且技術領先的Java開源報表庫。它將.jrxml(XML源文件)編譯為.jasper(編譯后版本)文件,它可以被轉換為多種格式輸出(PDF、CSV、XLS和HTML)。本節以一個例子講述JasperReports在Struts2中是如何配置和使用的。關于JasperReports的原理和詳細使用方法請參考JasperReports自身文檔。
6.8.1 準備JasperReports庫
在使用JasperReports之前,需要將JR庫添加到classpath。可以從“http://www.sourceforge.net/projects/jasperreports”下載JR項目。將jasperreports-X-project.zip存儲到硬盤,將文件解壓縮。需要如下文件:
? dist/jasperreports-X.jar
? lib/commons-*.jar (all the commons-except maybe for commons-logging)
? lib/itext-X.jar
? lib/jdt-compiler.jar
將這些jar拷貝到/WEB-INF/lib目錄,然后將它們添加到CLASSPATH。
JasperReports在Struts2中是作為一個plugin出現的,需要在Struts2包提供的lib目錄中找到struts2-jasperreports-plugin-xxx.jar,把這個jar文件也添加到/WEB-INF/lib目錄,同樣添加到CLASSPATH。
6.8.2 定義值對象
先定義一個簡單的POJO(簡單的Java對象,Plain Old Java Objects),實際就是普通JavaBeans。使用POJO名稱是為了和EJB區分,而且簡稱比較直接。有一些屬性及其getter、setter方法的類,有時可以作為值對象來使用,如實例6-29所示。
【實例6-29】關于對象類:Person.java
01 /* 02 *簡單POJO不包含任何復雜邏輯 03 */ 04 public class Person { 05 //創建各種變量 06 private Long id; //創建id變量 07 private String name; //創建name變量 08 private String lastName; //創建lastName 變量 09 //無參數構造函數 10 public Person() { 11 } 12 //帶參構造函數 13 public Person(String name, String lastName) { 14 this.name = name; 15 this.lastName = lastName; 16 } 17 //帶參構造函數 18 public Person(Long id, String name, String lastName) { 19 this.id = id; 20 this.name = name; 21 this.lastName = lastName; 22 } 23 /** 24 * @返回 id 25 */ 26 public Long getId() { 27 return id; 28 } 29 30 /** 31 * @id的setter方法 32 */ 33 public void setId(Long id) { 34 this.id = id; 35 } 36 37 /** 38 * @返回 lastName 39 */ 40 public String getLastName() { 41 return lastName; 42 } 43 44 /** 45 * @ lastName 的setter方法 46 */ 47 public void setLastName(String lastName) { 48 this.lastName = lastName; 49 } 50 51 /** 52 * @返回 name 53 */ 54 public String getName() { 55 return name; 56 } 57 58 /** 59 * @name屬性的setter方法 60 */ 61 public void setName(String name) { 62 this.name = name; 63 } 64 }
【代碼剖析】在上述代碼中,首先定義了三個成員變量id、name和lastName,然后又創建了三個構造函數,最后為所有的成員變量創建getter和setter方法。
6.8.3 編寫action類
JasperAction創建了一些人員的列表。JasperCompileManager會將jrxml模板編譯為.jasper文件。在實際程序中不要這樣做,不需要在每個請求中都把jrxml文件編譯為jasper文件,只需要執行一次就可以了,發布的時候直接使用jasper文件就可以了,如實例6-30所示。
【實例6-30】關于action類:ActionSupport.java
01 package jasperreports; 02 import java.io.File; 03 import java.util.*; 04 import net.sf.jasperreports.engine.JasperCompileManager; 05 import org.apache.struts2.ServletActionContext; 06 public class ActionSupport extends com.opensymphony.xwork2.ActionSupport { 07 // 這個list是作為數據源存在的 08 private List myList; 09 public String execute() throws Exception { //重寫執行方法 10 Person p1 = new Person(new Long(1), "Patrick", "Lightbuddie"); 11 Person p2 = new Person(new Long(2), "Jason", "Carrora"); 12 Person p3 = new Person(new Long(3), "Alexandru", "Papesco"); 13 Person p4 = new Person(new Long(4), "Jay", "Boss"); 14 /* 15 * 把數據保存到一個list中去, 一般情況下這些數據可能來自于數據庫, 本例 16 子中為了簡單直接在程序中賦值 17 */ 18 myList = new ArrayList(); 19 myList.add(p1); 20 myList.add(p2); 21 myList.add(p3); 22 myList.add(p4); 23 /* 24 * 把 xml jasper 模板編譯為一個jasper文件。在實際程序中不要這樣做, 不需 25 要每個請求都把jrxml文件編譯為jasper文件 26 * 直接使用jasper文件就可以了 27 */ 28 try { 29 String reportSource; 30 reportSource = ServletActionContext.getServletContext() 31 .getRealPath("/jasper/jasper_template.jrxml"); 32 File parent = new File(reportSource).getParentFile(); 33 JasperCompileManager.compileReportToFile(reportSource, new 34 File( 35 parent, 36 "jasper_template.jasper").getAbsolutePath()); 37 } catch (Exception e) { 38 e.printStackTrace(); 39 return ERROR; 40 } 41 // 返回成功字符串 42 return SUCCESS; 43 } 44 /** 45 * @return 返回 myList. 46 */ 47 public List getMyList() { //關于變量myList的getter方法 48 return myList; 49 } 50 }
【代碼剖析】在上述代碼中為了方便,手動創建了一個包含4個Person對象的myList集合,然后通過相關方法把jrxml模塊編譯成一個jasper文件,最后返回成功字符串SUCCESS。為了便于操作,還專門創建了一名為myList的成員變量,并設置該變量的getter方法。
6.8.4 編寫Jasper模板
JR使用一種特殊的XML頁面來定義模板,它會被編譯為.jasper文件。這些模板將會被用來設計結果報表。本例中展示的是一個手寫的版本,對于更加復雜的模板建議使用Jasper相關的GUI設計器(如ireport)來定義。
將文件存儲到工程的目錄下的“WW_WEBAPP/jasper”目錄(此目錄名是固定的不能改變),命名為“jasper_template.jrxml”。最重要的:聲明了name和lastName字段(這兩個屬性來自Person.class)。這意味著現在可以在Jasper模板中使用這些字段。
定義了兩個表頭(NAME和LASTNAME),然后將字段添加到一行的detail band。detail band將會從人員的List中迭代。這是JR的默認行為,所以如果想顯示人員的更多信息,把它們添加到這個band中。
在detail band使用了
$F{name}
這意味著JR會詢問Struts如何獲取字段的值。將會從Struts值棧中尋找這些值(尋找人員,調用getName()這個getter),然后返回它后面的:
$F{lastName}
余下部分的大部分標記用來定義布局,如實例6-31所示。
【實例6-31】JasperReports模板:jasper_template.jrxml
01 <?xml version="1.0"?> 02 <!DOCTYPE jasperReport 03 PUBLIC "-//JasperReports//DTD Report Design//EN" 04 "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"> 05 <jasperReport name="jasper_test"> 06 <!--our fields--> 07 <field name="name" class="java.lang.String"/> 08 <field name="lastName" class="java.lang.String"/> 09 <title> 10 <band height="50"> 11 <staticText> 12 <reportElement x="0" y="0" style="width:180" height="15"/> 13 <textElement/> 14 <text> 15 <![CDATA[Webwork JasperReports Sample]]> 16 </text> 17 </staticText> 18 </band> 19 </title> 20 <pageHeader> 21 <band></band> 22 </pageHeader> 23 <columnHeader> 24 <band height="20"> 25 <staticText> 26 <reportElement x="180" y="0" style="width:180" height="20"/> 27 <textElement> 28 <font isUnderline="true"/> 29 </textElement> 30 <text> 31 <![CDATA[NAME]]> 32 </text> 33 </staticText> 34 <staticText> 35 <reportElement x="360" y="0" style="width:180" height="20"/> 36 <textElement> 37 <font isUnderline="true"/> 38 </textElement> 39 <text> 40 <![CDATA[LASTNAME]]> 41 </text> 42 </staticText> 43 </band> 44 </columnHeader> 45 <detail> 46 <band height="20"> 47 <textField> 48 <reportElement x="180" y="0" style="width:180" height="15"/> 49 <textElement/> 50 <textFieldExpression> 51 <![CDATA[$F{name}]]> 52 </textFieldExpression> 53 </textField> 54 <textField> 55 <reportElement x="360" y="0" style="width:180" height="15"/> 56 <textElement/> 57 <textFieldExpression> 58 <![CDATA[$F{lastName}]]> 59 </textFieldExpression> 60 </textField> 61 </band> 62 </detail> 63 <columnFooter> 64 <band></band> 65 </columnFooter> 66 <pageFooter> 67 <band height="15"> 68 <staticText> 69 <reportElement x="0" y="0" style="width:40" height="15"/> 70 <textElement/> 71 <text> 72 <![CDATA[Page:]]> 73 </text> 74 </staticText> 75 <textField> 76 <reportElement x="40" y="0" style="width:100" height="15"/> 77 <textElement/> 78 <textFieldExpression class="java.lang.Integer"> 79 <![CDATA[$V{PAGE_NUMBER}]]> 80 </textFieldExpression> 81 </textField> 82 </band> 83 </pageFooter> 84 <summary> 85 <band></band> 86 </summary> 87 </jasperReport>
【代碼剖析】在上述代碼中大部分內容都是自動生成的,所以這里就不詳細介紹了。
6.8.5 配置struts.xml
將action添加到struts.xml,給這個action配置一個類型為jasper的result。Jasper類型的result不是Struts2默認就提供的,而是作為一個plugin出現,所以在配置中要繼承包jasperreports-default,如實例6-32所示。
【實例6-32】JasperReports配置文件:struts.xml
01 <!DOCTYPE struts PUBLIC 02 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 03 "http://struts.apache.org/dtds/struts-2.0.dtd"> 04 <struts> 05 <!--JasperReports在struts.xml中的配置 --> 06 <package name="default" extends="struts-default,jasperreports-default"> 07 <action name="PDF" class="jasperreports.ActionSupport"> 08 <result name="success" type="jasper"> 09 <param 10 name="location">/jasper/jasper_template.jasper</param> 11 <param name="dataSource">myList</param> 12 <param name="format">PDF</param> 13 </result> 14 </action> <!--當請求參數為HTML時--> 15 <action name="HTML" class="jasperreports.ActionSupport"> 16 <result name="success" type="jasper"> 17 <param 18 name="location">/jasper/jasper_template.jasper</param> 19 <param name="dataSource">myList</param> 20 <param name="format">HTML</param> 21 </result> 22 </action> <!--當請求參數為XML時--> 23 <action name="XML" class="jasperreports.ActionSupport"> 24 <result name="success" type="jasper"> 25 <param 26 name="location">/jasper/jasper_template.jasper</param> 27 <param name="dataSource">myList</param> 28 <param name="format">XML</param> 29 </result> 30 </action> <!--當請求參數為CSV時--> 31 <action name="CSV" class="jasperreports.ActionSupport"> 32 <result name="success" type="jasper"> 33 <param 34 name="location">/jasper/jasper_template.jasper</param> 35 <param name="dataSource">myList</param> 36 <param name="format">CSV</param> 37 </result> 38 </action> <!--當請求參數為XLS時--> 39 <action name="XLS" class="jasperreports.ActionSupport"> 40 <result name="success" type="jasper"> 41 <param 42 name="location">/jasper/jasper_template.jasper</param> 43 <param name="dataSource">myList</param> 44 <param name="format">XLS</param> 45 </result> 46 </action> 47 </package> 48 </struts>
【代碼剖析】
1)將ActionSupport注冊為“PDF”這意味著可以在瀏覽器中通過PDF.action發出請求來執行這個Action。
2)當ActionSupport執行正確,由于繼承了jasperreports-default,它就已經被配置好了。所以報表類型已經配置好。
<result name="success" type="jasper">
3)這種result type根據參數params配置。配置如下:
<param name="location">/jasper/jasper_template.jasper </param>
4)這個參數定義了編譯好的jasper文件的位置,它將被Struts根據的數據源dataSource填充。數據源的名稱就是需要調用的getter的名字(上面的配置會調用JasperAction中的getMyList()方法):
<param name="dataSource">myList</param>
5)它將被用來以數據填充模板,這一行指定了jasper被轉換成的文件格式。值可以是PDF、CSV、XLS和HTML:
<param name="format">PDF</param>
注意
生成HTML報表時jasperreports會引用到WebRoot/images下一個名為px的文件(沒有擴展名)。可以將jasperreports-2.0.2\net\sf\jasperreports\engine\images下的pixel.GIF文件復制到這個目錄下并重命名為px。
- 高手是如何做產品設計的(全2冊)
- Mastering NetBeans
- Testing with JUnit
- Manga Studio Ex 5 Cookbook
- Machine Learning with R Cookbook(Second Edition)
- Learning Bayesian Models with R
- NativeScript for Angular Mobile Development
- React.js Essentials
- KnockoutJS Starter
- .NET 3.5編程
- 編程菜鳥學Python數據分析
- iOS開發項目化入門教程
- Java Script從入門到精通(第5版)
- Android項目實戰:博學谷
- Roslyn Cookbook