Generate Jasper Reports in Java Tutorial with data source connection in Struts

This article shows you how to generate dynamic reports from data stored in the database using the open source Java reporting tool Jasper Reports. Jasper Reports uses XML templates to generate reports that can be saved as PDF or CSV, HTML, XLS

Steps to generate a report using JasperReports:

1. Create an XML document that defines the composition of the report. This XML document is a reusable template that the reporting engine populates with data from the database. This template (JRXML file / XML file) is used to provide the information that the reporting engine needs to create the report, such as a sql query string to retrieve data from db, fonts, title of report, names of image files, page headers and footers, column headers, and a summary section. The structure of XML template is defined in an XML DTD file named jasperreport.dtd that is included in the JasperReports distribution. This DTD contains the different sections such as Title, queryString, PageHeader, PageFooter, ColumnHeader, ColumnFooter, Detail, Summary, etc that can be included in the XML template.

The XML template can be created by using IReports OR by editing the existing XML template file as per your requirement. To simplify your task, an sample XML template file is given in the last section of this article which is used in our example. Once you have created your XML template file, you have to follow the below steps.

2. Place the XML template in a filesystem (/JReports/…jrxml). Compile the XML template using IReports or using java code that yields a serialized object (.jasper file). You need to specify a directory (eg. JReports under WebContent folder) to store the compiled version of the XML template. Whenever an XML template is compiled, it is saved with the extension .jasper in the same folder where XML template file is stored. The following code compiles the JREmployee.jrxml and creates JREmployee.jasper in the folder JReports.

JasperCompileManager.compileReportToFile(getServletContext().getRealPath(“/JReports/JREmployee.jrxml”));

You can use this compiled version of XML template multiple times with different sets of data. The reporting engine uses the compiled version with parameters passed and SQL Query defined in the XML template to create a dynamic report (i.e. modifying the report data at run time such as the report title, or a WHERE clause of the query string that will be used to collect the data from the database)

3. Load the .jasper file with JRLoader.loadObject method which returns the JasperReport instance.


File jreportFile = new File(getServletContext().getRealPath("/JReports/JREmployee.jasper"));
 JasperReport jreport = (JasperReport) JRLoader.loadObject(jreportFile.getPath());

where the jreport is an instance of a compiled XML template.

If JREmployee.jasper does not exisit , then you can compile the .jrxml file to .jasper using java code with the following lines.

if (!jreportFile.exists()) {
JasperCompileManager.compileReportToFile(getServletContext().getRealPath("/JReports/" + fileName + ".jrxml"));
}

which is useful when you need to modify report data at run time

4. Now pass the jreport instance, parameters and connection object to methods like JasperRunManager.runReportToPdf(), JasperManager.fillReport() to generate the report in any formats such as PDF or HTML format where the parameters are the instance of java.util.Map that contains the parameters such as title of the report, variables to be passed to the sql query.

The connection object is the instance of java.sql.Connection that connects to the database ( here db name is employee). This java.sql.Connection object is obtained from the datasource object (jdbc/employeeDS – JNDI name).

For converting to HTML :

Use the JasperManager.fillReport method to generate a report and use JRHtmlExporter to export the report in HTML format. JasperManager.fillReport accepts report instance , parameters and connection object returns a JasperPrint object, which represents an instance of a report:


private void generateReportHtml( JasperPrint jasperPrint, HttpServletRequest req, HttpServletResponse resp ) throws IOException, JRException {
   Map imagesMap = new HashMap();
   JRHtmlExporter exporter = new JRHtmlExporter();
   exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
   exporter.setParameter( JRExporterParameter.OUTPUT_WRITER, resp.getWriter());
   exporter.exportReport();
}

For Generating PDF:

Use JasperRunManager.runReportToPdf to regenerate report in PDF format . JasperRunManager.runReportToPdf accepts response object , report instance , parameters and connection object and returns a JasperPrint object, which represents an instance of a report:

private void generatePDFOutput( HttpServletResponse resp, Map parameters, JasperReport jasperReport) throws JRException, NamingException, SQLException, IOException {
byte[] bytes = null;
bytes = JasperRunManager.runReportToPdf(jasperReport,parameters,conn);
resp.reset();
resp.resetBuffer();
resp.setContentType("application/pdf");
resp.setContentLength(bytes.length);
ServletOutputStream ouputStream = resp.getOutputStream();
ouputStream.write(bytes, 0, bytes.length);
ouputStream.flush();
ouputStream.close();

} 

JasperReports libraries:

Before we can continue, we need to add the Jasper Libraries to classpath. We may need the following jar files to create and run the JasperReport

jasperreports-X.jar
commons-*.jar
iText-X.jar
groovy-all-1.5.5.jar
bsh-*.jar

Copy the jar files to your WebContent\WEB-INF\lib directory, and add them to your classpath.

Direct link to download the JasperReport Libraries (jasperreports-3.5.3.jar, JasperReports 3.6.0, JasperReports 3.6.1 , ….JasperReports 4.7.1 (latest version) is

http://sourceforge.net/projects/jasperreports/files/jasperreports/
In this example, jasperreports-3.5.3.jar is used. The following sample Web application shows you how to create dynamic reports in HTML and PDF format. This application can be developed MyEclipse / WSAD  / RAD and use MySql or  any  database. The whole program is as follows …


public ActionForward loadEmpDetailsReport( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

ActionErrors errors = new ActionErrors();

ActionForward forward = new ActionForward();

String strTarget="";

try {

Connection conn = null;

Map parameters = new HashMap();

// request.getParameter("reportFormat");

//String reportFormat ="HTML";

String reportFormat ="PDF";

String reportFileName = "";

reportFileName = "JREmployee";

parameters.put("bp", new Integer(5000));

parameters.put("Title", "Employee Details");

try {

conn = ConnectionFactory.getConnection();  //to get connection from pool

JasperReport jasperReport = getCompiledFile(reportFileName, request);

if (reportFormat.equalsIgnoreCase("HTML") ) {

JasperPrint jasperPrint = JasperManager.fillReport(jasperReport, parameters, conn);

generateReportHtml(jasperPrint, request, response); // For HTML report

}

else {

generateReportPDF(response, parameters, jasperReport, conn); // For PDF report

}

} catch (Exception sqlExp) {

System.out.println( "Exception::" + sqlExp.toString());

} finally {

try {

if (conn != null) {

conn.close();

conn = null;

}

} catch (SQLException expSQL) {

System.out.println("SQLExp::CLOSING::" + expSQL.toString());

}

}

strTarget = null;

} catch (Exception e) {

errors.add("name", new ActionError("id"));

strTarget = "failure";

}

if (!errors.isEmpty()) {

saveErrors(request, errors);

strTarget = "failure";

}

forward = mapping.findForward(strTarget);

return (forward);

}  

private JasperReport getCompiledFile(String fileName, HttpServletRequest request) throws JRException {
File reportFile = new File( request.getSession().getServletContext().getRealPath("/JReports/" + fileName + ".jasper"));
// If compiled file is not found, then compile XML template
if (!reportFile.exists()) {
           JasperCompileManager.compileReportToFile(request.getSession().getServletContext().getRealPath("/JReports/" + fileName + ".jrxml"));
    }
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(reportFile.getPath());
return jasperReport;
} 

private void generateReportHtml( JasperPrint jasperPrint, HttpServletRequest req, HttpServletResponse resp) throws IOException, JRException {
Map imagesMap = new HashMap();
JRHtmlExporter exporter = new JRHtmlExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter( JRExporterParameter.OUTPUT_WRITER, resp.getWriter());
exporter.exportReport();
} 

private void generateReportPDF (HttpServletResponse resp, Map parameters, JasperReport jasperReport, Connection conn)throws JRException, NamingException, SQLException, IOException {
byte[] bytes = null;
bytes = JasperRunManager.runReportToPdf(jasperReport,parameters,conn);
resp.reset();
resp.resetBuffer();
resp.setContentType("application/pdf");
resp.setContentLength(bytes.length);
ServletOutputStream ouputStream = resp.getOutputStream();
ouputStream.write(bytes, 0, bytes.length);
ouputStream.flush();
ouputStream.close();
} 

public class ConnectionFactory {
public static Connection getConnection() throws CDRCFatalException {
Context ctxLookup = null;
DataSource ds = null;
Connection conn= null;
try {
ctxLookup = new InitialContext();
ds = (javax.sql.DataSource) ctxLookup.lookup("jdbc/employeeDS");
} catch (NamingException e) { throw new CDRCFatalException( e.getMessage(), "01001" );
}

try {
conn = ds.getConnection();
}catch (SQLException e) { throw new CDRCFatalException( e.getMessage(), "02006");
}
return conn;
} 

For running the program, create a database employee, and create a table emp with fields empcode varchar, empname varchar, basic decimal and insert some records. Create a datasource employeeDS for the database employee. Running the program will return the all employees whose basicpay is greater than or equal to 5000.

JREmployee.jrxml


<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="EmployeeReport" pageWidth="500" pageHeight="600" columnWidth="450" leftMargin="5" rightMargin="5" topMargin="10" bottomMargin="1> <reportFont name="Arial" isDefault="true" fontName="Arial" size="11" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>

<parameter name="Title" class="java.lang.String"/>
<parameter name="emp_code" class="java.lang.String"/>
<parameter name="bp" class="java.lang.Integer"/>
<queryString>
<![CDATA[select empcode, empname, basic from emp where basic>=$P{bp}]]>
</queryString>

<field name="empcode" class="java.lang.String"/>
<field name="empname" class="java.lang.String"/>
<field name="basic" class="java.lang.Integer"/>

<title>
<band height="50" splitType="Stretch">
<textField isBlankWhenNull="true">
<reportElement x="40" y="0" width="370" height="30"/>
<textElement textAlignment="Center">
<font reportFont="Arial" size="22"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{Title}]]></textFieldExpression>
</textField>
</band>
</title>

<pageHeader>
<band height="20" splitType="Stretch">
<textField>
<reportElement mode="Opaque" x="0" y="5" width="490" height="15" forecolor="#FFFFFF" backcolor="#777765"/>
<textElement textAlignment="Center">
<font reportFont="Arial_Bold"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA["Employees whose Basic is greater than " + String.valueOf($P{bp})]]></textFieldExpression>
</textField>
</band>
</pageHeader>

<columnHeader>
<band height="20" splitType="Stretch">
<staticText>
<reportElement mode="Opaque" x="0" y="4" width="170" height="15" backcolor="#CBB453"/>
<textElement textAlignment="Left">
<font reportFont="Arial_Bold"/>
</textElement>
<text><![CDATA[EMP Code]]></text>
</staticText>

<staticText>
<reportElement positionType="Float" mode="Opaque" x="170" y="4" width="170" height="15" backcolor="#CBB453"/>
<textElement>
<font reportFont="Arial_Bold"/>
</textElement>
<text><![CDATA[Emp Name]]></text>
</staticText>

<staticText>
<reportElement positionType="Float" mode="Opaque" x="340" y="4" width="150" height="15" backcolor="#CBB453"/>
<textElement>
<font reportFont="Arial_Bold"/>
</textElement>
<text><![CDATA[Basic Pay]]></text>
</staticText>
</band>
</columnHeader>

<detail>
<band height="20" splitType="Stretch">
<textField>
<reportElement x="0" y="4" width="170" height="15"/>
<textElement textAlignment="Left"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{empcode}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" x="170" y="4" width="170" height="15"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{empname}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="true">
<reportElement positionType="Float" x="340" y="4" width="150" height="15"/>
<textElement/>

<textFieldExpression class="java.lang.Integer"><![CDATA[$F{basic}]]></textFieldExpression>
</textField>
</band>
</detail>

<pageFooter>
<band height="40" splitType="Stretch">
<textField>
<reportElement x="200" y="20" width="85" height="15"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.lang.String"><![CDATA["Page " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="285" y="20" width="75" height="15"/>
<textElement textAlignment="Left"/>
<textFieldExpression class="java.lang.String"><![CDATA[" of " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
</textField>
</band>
</pageFooter>

<summary>
<band height="35" splitType="Stretch">
<textField isStretchWithOverflow="true">
<reportElement x="175" y="20" width="165" height="15"/>
<textElement textAlignment="Center">
<font reportFont="Arial"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA["Total Number of Employees " +
String.valueOf($V{REPORT_COUNT})]]></textFieldExpression>
</textField>
</band>
</summary>

</jasperReport>

In the above XML template

pdfFontName – an equivalent PDF font name required by the iText library when exporting documents to PDF format.
pdfEncoding – the equivalent PDF character encoding, required by the iText library.
isPdfEmbedded – flag that specifies whether the font should be embedded into the document itself. Default value is false.

 Reference : Generating online reports using JasperReports and WebSphere Studio

You may also like

Leave a Reply