In previous post we have made Person model (POJO) and DAO also manager to perform CRUD on person object. Now we will generate report of person list by using JasperReports and IReport. We use IReport to make .jrxml file that needed by JasperReports. This tool is so powerful because easy to use and GUI based. Here we start. Download first JasperReports libraries and IReport application. Copy JasperReports libraries folder into AppfuseExample lib folder. Edit lib.properties file.
#
#Jasper
#
jasper.version=1.2.0
jasper.dir=${lib.dir}/jasperreports-${jasper.version}
jasper.jar=${jasper.dir}/jasperreports-1.2.0.jar
Create a class to generate report in package com.ndung.util named ReportUtil.java.
package com.ndung.util;
import java.io.*;
import java.util.*;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.*;
import net.sf.jasperreports.engine.util.JRLoader;
public class ReportUtil {
public static void generateReport(String templateFilename, String outputFilename, List data,
Map<String, Object> reportParameters, String fileType) {
try {
OutputStream os = new FileOutputStream(outputFilename);
generateReport(templateFilename, os, data, reportParameters, fileType);
os.close();
} catch (IOException e) { e.printStackTrace(); }
}
public static void generateReport(String templateFilename, OutputStream os, List data,
Map<String, Object> reportParameters, String fileType) {
String reportFileName = ReportUtil.class.getResource("/" + templateFilename).getFile();
if(reportParameters == null)
reportParameters = new HashMap<String, Object>();
try {
JasperPrint jasperPrint;
JasperReport jasperReport = getCompiledReport(reportFileName);
jasperPrint = JasperFillManager.fillReport(jasperReport, reportParameters,
new JRBeanCollectionDataSource(data));
JRExporter exporter = null;
if (fileType.equals("txt")) exporter = new JRTextExporter();
else if (fileType.equals("csv")) exporter = new JRCsvExporter();
else if (fileType.equals("xls")) exporter = new JRXlsExporter();
else exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.exportReport();
} catch (Exception e) { e.printStackTrace(); } }
private static JasperReport getCompiledReport(String reportFileName) throws JRException {
File reportFile = new File(reportFileName.replace("jrxml", "jasper"));
if (!reportFile.exists())
JasperCompileManager.compileReportToFile(reportFileName);
return (JasperReport) JRLoader.loadObject(reportFile.getPath());
}
}
Now open IReport to make jrxml file. Click File -> New Document. Fill report name with PersonsReport.jrxml. Click Tools -> Classpath. Add jar/folder where our classes built. As example: /home/ndung/workspace/AppfuseExample/bin. Click Datasource -> Report Query, in tab JavaBean Datasource, fill class name with com.ndung.model.Person and click Read javabeans attributes. If your classpath right, it will read attributes of person. Create document like picture below by dragging fields or variables or parameters in right panel (library). Save this file into folder src/web. Try to compile this file by clicking button compile. If there is no error, it will be compiled successfully. If this file has been compiled it will generate file .jasper. Check out PersonsReport.jasper in your computer folder.
We will add a page special that can be called from menu directly. In package com.ndung.webapp.action create a class named PersonReport.java. In folder web/pages create two files named personReport.html and personReport.page.
package com.ndung.webapp.action;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import com.ndung.model.Person;
import com.ndung.service.Manager;
import com.ndung.util.ReportUtil;
public abstract class PersonReport extends BasePage{
public abstract Manager getManager();
public void generate() throws IOException{
List persons = getManager().getObjects(Person.class);
OutputStream os = getResponse().getOutputStream();
getResponse().addHeader( "Content-Disposition", "attachment; filename=report.zip");
getResponse().setContentType( "application/zip" ) ;
os = new ZipOutputStream( os );
String templateFilename = "PersonsReport.jrxml";
Map<String, Object> mapReport = new HashMap<String, Object>();
mapReport.put("title", "Persons Report"); mapReport.put("date", new Date());
((ZipOutputStream)os).putNextEntry( new ZipEntry("PersonsReport.pdf" ) ) ;
ReportUtil.generateReport(templateFilename, os, persons, mapReport, "pdf");
((ZipOutputStream)os).closeEntry() ;
os.flush();
os.close();
}
}
<span jwcid="@ShowValidationError" delegate="ognl:beans.delegate"/>
<span jwcid="@ShowMessage"/>
<form jwcid="form">
<input type="submit" class="button" jwcid="@Submit" value="message:button.generate" id="save" action="listener:generate"/>
</form>
<?xml version="1.0"?>
<!DOCTYPE page-specification PUBLIC
"-//Apache Software Foundation//Tapestry Specification 4.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
<page-specification class="com.ndung.webapp.action.PersonReport">
<inject property="request" object="service:tapestry.globals.HttpServletRequest"/>
<inject property="response" object="service:tapestry.globals.HttpServletResponse"/>
<inject property="manager" type="spring" object="manager"/>
<bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
<component id="form" type="Form">
<binding name="delegate" value="ognl:beans.delegate"/>
<binding name="clientValidationEnabled" value="true"/>
</component>
</page-specification>
In tapestry application add mapping file for .page and .html.
<page name="personReport" specification-path="pages/personReport.page"/>
Edit ApplicationResources.properties and build.xml like belows.
menu.person=Person
menu.person.list=Person List
menu.person.report=Person Report
personreport.heading=Person Report
personreport.title=Person Report
button.generate=Generate
<target name="package-web" ...>
...
<copy todir="${build.dir}/web/classes">
<fileset dir="src/web">
...
<include name="**/*.jrxml"/>
<include name="**/*.jasper"/>
</fileset>
</copy>
...
<war destfile="${webapp.dist}/${webapp.war}" duplicate="preserve" ,,,>
...
<lib dir="${jasper.dir}" includes="*.jar"/>
</war>
</target>
Last, add menu for this feature.
insert into menu(id,name,url,parent) values(10,"menu.person",null,null);
insert into menu(id,name,url,parent) values(11,"menu.person.list","persons.html",10);
insert into menu(id,name,url,parent) values(12,"menu.person.report","personsReport.html",10);
insert into role_menu(role_id,menu_id) values(1,10);
insert into role_menu(role_id,menu_id) values(2,10);
insert into role_menu(role_id,menu_id) values(1,11);
insert into role_menu(role_id,menu_id) values(2,11);
insert into role_menu(role_id,menu_id) values(1,12);
insert into role_menu(role_id,menu_id) values(2,12);
Read More..