IntroductionJasperReports (http://jasperreports.sourceforge.net) is one of the leading open-source java reporting libraries. It compiles .jrxml (XML source) to .jasper (=compiled version) files, which in turn can be transformed to several output types (PDF, CSV, XLS and HTML). In the following example, we will use Webwork to dynamically create a PDF with a list of persons. Our WW action will be used to create a List with objects, and our JasperReport Result will use this list to fill our template, and return the PDF. I assume you already have a WW webapp working.
Right, let's begin. Our Person classWe start by defining a simple POJO class: Person.java com.mevipro.test.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; } } Nothing special. Just your basic properties, constructor, getters and setters. JasperReports librariesBefore we can continue, we need to add the JR libraries to our classpath. You can download the JR project here: http://www.sourceforge.net/projects/jasperreports We need the following files:
Copy these jars over to your WW_WEBAPP/WEB-INF/lib directory, and add them to your classpath. Show me the Actioncom.mevipro.test.action.JasperAction 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; } } Once again - I guess everything is pretty clear. Our JasperAction will create a list of several People. The JasperCompileManager will then compile the jrxml template to a .jasper file.
Our Jasper templateJR uses a special XML page to define templates which will be compiled to .jasper files. These templates will be used to design the resulting report. It's pretty straightforward. our_jasper_template.jrxml <?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> Save this file in WW_WEBAPP/jasper/ as 'our_jasper_template.jrxml'. Most important: we declared the fields name and lastName (not surprisingly, two properties from our Person.class). This means we will now be able to use these fields in our Jasper template. We define two columnheaders (NAME and LASTNAME), and then add our fields to the detail band (for a better explanation, look at the JR tutorial). This 'detail' band will iterate over our List of People. This is the default behaviour of JR - so if you want to display more information from the Person, add them to this band. In the detail band we use the $F{name} $F{lastName} The rest is mostly markup to define the layout.
Register the ActionAlright, time to add the action to our xwork.xml file: 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> Let's explore this a bit further. I assume you are familiar with the xwork notation & schema, if not, check the documentation. <action name="myJasperTest" class="com.mevipro.test.action.JasperAction"> We simply register our JasperAction with the name 'myJasperTest' - this means that we can execute this Action by sending a request to myJasperTest.action in our browser. <result name="success" type="jasper"> When our JasperAction executes correctly, we will use the Result type registered with the name 'jasper'. This is already done when you include the webwork-default ( <include file="webwork-default.xml"/>
<param name="location">/jasper/our_compiled_template.jasper</param>
This parameter defines the location of our compiled jasper file, which will be filled by WW with our dataSource: <param name="dataSource">myList</param>
The name of the dataSource - this is the name of the getter you want to call (this will result in a getMyList() call to your JasperAction). It will be used to fill the template with data. <param name="format">PDF</param>
This specifies the format to which the jasper file will be transformed. Possible values are: PDF, CSV, XLS and HTML. ConclusionYou should now be able to execute http://localhost:8080/YOUR_WEBAPP/myJasperTest.action - and you should see a nice list of names. |