JasperReports - WebWork2
介绍
JasperReports(http://jasperreports.sourceforge.net
)是领先的java开源报表库. 它将.jrxml(XML源文件)编译为.jasper(=编译后版本)文件, 它可以被转换为多种格式输出(PDF, CSV, XLS and HTML).
下面的例子, 我们使用Webwork动态创建人员列表的PDF文件. 我们的WW action用来创建对象的List, 而JasperReport Result用这个list来填充模版, 返回PDF文件.
我们假设你已经掌握WW web应用程序基本知识.
|
注意: 虽然例子非常简单, 我还是建议你详细的阅读WW和JR的相关文档. |
| 使用的版本 Webwork 2.2 beta 3 (但是在以前的版本下也应该可以工作) |
好的, 我们开始.
代码
我们先定义一个简单的POJO: Person.java
package com.mevipro.test; public class Person { private Long id; private String name; private String lastName; public Person() { super(); } public Person(String name, String lastName) { super(); this.name = name; this.lastName = lastName; } public Person(Long id, String name, String lastName) { super(); this.id = id; this.name = name; this.lastName = lastName; } /** * @return Returns the id. */ public Long getId() { return id; } /** * @param id The id to set. */ public void setId(Long id) { this.id = id; } /** * @return Returns the lastName. */ public String getLastName() { return lastName; } /** * @param lastName The lastName to set. */ public void setLastName(String lastName) { this.lastName = lastName; } /** * @return Returns the name. */ public String getName() { return name; } /** * @param name The name to set. */ public void setName(String name) { this.name = name; } }
没什么特殊之处. 只有简单的属性, 构造方法, 还有getters和setters.
JasperReports库
在我们继续之前, 我们需要将JR库添加到classpath. 你可以从这里
下载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拷贝到你的WW_WEBAPP/WEB-INF/lib目录, 然后将它们添加到你的classpath.
让我们看看Action
package com.mevipro.test.action; import java.util.ArrayList; import java.util.List; import net.sf.jasperreports.engine.JasperCompileManager; import com.mevipro.test.Person; import com.opensymphony.xwork.ActionSupport; public class JasperAction extends ActionSupport { //basic List - it will serve as our dataSource later on private List myList; /* * (non-Javadoc) * * @see com.opensymphony.xwork.ActionSupport#execute() */ public String execute() throws Exception { // create some imaginary persons Person p1 = new Person(new Long(1), "Patrick", "Lightbuddie"); Person p2 = new Person(new Long(2), "Jason", "Carrora"); Person p3 = new Person(new Long(3), "Alexandru", "Papesco"); Person p4 = new Person(new Long(4), "Jay", "Boss"); /* * store everything in a list - normally, this should be coming from a * database but for the sake of simplicity, I left that out */ myList = new ArrayList(); myList.add(p1); myList.add(p2); myList.add(p3); myList.add(p4); /* * Here we compile our xml jasper template to a jasper file. * Note: this isn't exactly considered 'good practice'. * You should either use precompiled jasper files (.jasper) or provide some kind of check * to make sure you're not compiling the file on every request. * If you don't have to compile the report, you just setup your data source (eg. a List) */ try { JasperCompileManager.compileReportToFile( "WW_WEBAPP/jasper/our_jasper_template.jrxml", "WW_WEBAPP/jasper/our_compiled_template.jasper"); } catch (Exception e) { e.printStackTrace(); return ERROR; } //if all goes well .. return SUCCESS; } /** * @return Returns the myList. */ public List getMyList() { return myList; } }
和刚才的代码一样--无需解释就很清楚了. 我们的JasperAction创建了一些人员的list. JasperCompileManager会将jrxml模版编译为.jasper文件.
|
不要在实际工作状态(production code)这样使用. 你当然应该提供编译后的模版文件, 或者做好变更检测, 来避免在每次请求时都重新编译模版. 但是在我们演示或者开发的过程中这样的方式很方便. |
我们的Jasper模版
JR使用一种特殊的XML页面定义模版, 它会被编译为.jasper文件. 这些模版将会被用来设计结果报表. 它相当直接.
这是一个手写的版本 - 对于更加复杂的版本我强烈建议你看看各种各样的GUI设计器.
<?xml version="1.0"?> <!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"> <jasperReport name="jasper_test"> <!-- our fields --> <field name="name" class="java.lang.String"/> <field name="lastName" class="java.lang.String"/> <title> <band height="50"> <staticText> <reportElement x="0" y="0" width="180" height="15"/> <textElement/> <text> <![CDATA[Webwork JasperReports Sample]]> </text> </staticText> </band> </title> <pageHeader> <band></band> </pageHeader> <columnHeader> <band height="20"> <staticText> <reportElement x="180" y="0" width="180" height="20"/> <textElement> <font isUnderline="true"/> </textElement> <text> <![CDATA[NAME]]> </text> </staticText> <staticText> <reportElement x="360" y="0" width="180" height="20"/> <textElement> <font isUnderline="true"/> </textElement> <text> <![CDATA[LASTNAME]]> </text> </staticText> </band> </columnHeader> <detail> <band height="20"> <textField> <reportElement x="180" y="0" width="180" height="15"/> <textElement/> <textFieldExpression> <![CDATA[$F{name}]]> </textFieldExpression> </textField> <textField> <reportElement x="360" y="0" width="180" height="15"/> <textElement/> <textFieldExpression> <![CDATA[$F{lastName}]]> </textFieldExpression> </textField> </band> </detail> <columnFooter> <band></band> </columnFooter> <pageFooter> <band height="15"> <staticText> <reportElement x="0" y="0" width="40" height="15"/> <textElement/> <text> <![CDATA[Page:]]> </text> </staticText> <textField> <reportElement x="40" y="0" width="100" height="15"/> <textElement/> <textFieldExpression class="java.lang.Integer"> <![CDATA[$V{PAGE_NUMBER}]]> </textFieldExpression> </textField> </band> </pageFooter> <summary> <band></band> </summary> </jasperReport>
将文件存储到WW_WEBAPP/jasper/, 命名为'our_jasper_template.jrxml'.
最重要的:我们声明了name和lastName字段(不奇怪, 这两个属性来自我们的Person.class). 这意味着我们现在可以在我们的Jasper模版中使用这些字段.
我们定义了两个表头(NAME和LASTNAME), 然后将我们的字段们添加到一行的detail band(详细的解释请参照JR的教程). 'detail' band将会从人员的List中迭代. 这是JR的默认行为 - 所以如果你想显示人员的更多信息, 把它们添加到这个band中.
在detail band我们使用了
$F{name}
表达式. 这意味着JR会询问WW如何获取字段的值. 我们将会从WW值栈中寻找这些值(寻找人员, 调用getName()这个getter), 然后返回它. 后面的也一样
$F{lastName}
余下部分的大部分标记用来定义布局.
|
如果你遇到困难,在debug状态下通过logger(commons-logging, log4j, ..)来观察com.opensymphony.webwork.views.jasperreports可以方便寻找问题所在. |
注册Action
好了, 可以将我们的action添加到xwork.xml了:
<action name="myJasperTest" class="com.mevipro.test.action.JasperAction"> <result name="success" type="jasper"> <param name="location">/jasper/our_compiled_template.jasper</param> <param name="dataSource">myList</param> <param name="format">PDF</param> </result> </action>
我们进一步看一看. 我假设你已经熟悉了xwork的符号和schema, 如果你还不熟悉请查阅文档.
<action name="myJasperTest" class="com.mevipro.test.action.JasperAction">
我们将我们的JasperAction注册为'myJasperTest' - 这意味着我们可以在浏览器中通过myJasperTest.action发出请求来执行我们的Action.
<result name="success" type="jasper">
当我们的JasperAction执行正确, 我们使用注册为'jasper'的Result type. 如果你include了webwork-default, 它就已经被配置好了
<include file="webwork-default.xml"/>
这种result type根据我们的参数params配置, 配置如下:
<param name="location">/jasper/our_compiled_template.jasper</param>
这个参数定义了我们编译好的jasper文件的位置, 它将被WW根据我们的数据源dataSource填充:
<param name="dataSource">myList</param>
数据源的名称 - 就是你需要调用的getter的名字(上面的配置会调用你的JasperAction中的getMyList()方法). 它将被用来以数据填充模版.
<param name="format">PDF</param>
这一行制定了jasper被转换成的文件格式. 值可以是: PDF, CSV, XLS and HTML.
结论
你现在可以执行http://localhost:8080/YOUR_WEBAPP/myJasperTest.action
- 然后你会看到一个不错的名字列表.
WW提供了处理JasperReport文件的最优雅解决方案(也许); 指定.jasper文件的位置, 指定你希望使用的数据源dataSource, 然后它就可以工作了.
需要在Web.xml文件中配置一个Servlet
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>net.sf.jasperreports.j2ee.servlets.ImageServlet</servlet-class>
</servlet>[来源www.iocblog.net]
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>[来源www.iocblog.net]
<url-pattern>/servlets/image</url-pattern>
</servlet-mapping>
文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
我直接生成html时,无法显示出图片,请问?这种方法生成的文件是存在好个位置的,如何设置!