Thursday, October 18, 2012

Generate Report by ZK Jasperreport Programmatically



Introduction

From the Related Posts below:

JasperReports is a powerful reporting engine which supports various formats including pdf, html, rtf, xls, doc etc, ZK has integrated JasperReports to leverage these powers for ease of reporting.

This post is about how to generate report programmtically, you can also find some different way in the Related Post below.

The Environment

Basic ZK 5.0.11 EE eval jars plus commons-digester-2.1.jar (can be found at http://archive.apache.org/dist/commons/digester/binaries/) and commons-beanutils-1.8.3.jar (downloaded from http://commons.apache.org/beanutils/download_beanutils.cgi, for generate template)

Note: the version of commons-digester should be 2.x or you may see NoClassDefFoundError with respect to org.apache.commons.digester.Rule

The Code

InfoResource.java

This class do two things (this is not good, but just for this post...)

1. call JasperCompileManager.compileReportToFile to compile the template.jrxml to template.jasper (the template used to generate report)

2. provide data to report

package test.report;

import java.util.ArrayList;
import java.util.List;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;
import net.sf.jasperreports.engine.JasperCompileManager;

public class InfoResource implements JRDataSource {
    private List<FoodInfo> dataList = new ArrayList<FoodInfo>();
    private int index = -1;
    public static void main(String args[]) {
        generateTemplateSrc();
    }
    /**
     * compile the template.jrxml to generate template.jasper
     */
    public static void generateTemplateSrc() {
        try {
            JasperCompileManager.compileReportToFile("WebContent/WEB-INF/template/template.jrxml", "WebContent/WEB-INF/template/template.jasper");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public InfoResource()
    {
        // datas to report
        dataList.add(new FoodInfo("pizza", 1000, 200));
        dataList.add(new FoodInfo("ham",  500, 300));
        dataList.add(new FoodInfo("banana", 200, 20));
    }

    /**
     * method defined in interface JRDataSource,
     * return whether has next data
     */
    public boolean next() throws JRException
    {
        index++;
        return (index < dataList.size());
    }
    /**
     * method defined in interface JRDataSource,
     * return value based on field name
     */
    public Object getFieldValue(JRField field) throws JRException
    {
        Object value = null;
        
        String fieldName = field.getName();
        
        if ("product_name".equals(fieldName))
        {
            value = dataList.get(index).getName();
        }
        else if ("cal".equals(fieldName))
        {
            value = dataList.get(index).getCal();
        }
        else if ("price".equals(fieldName))
        {
            value = dataList.get(index).getPrice();
        }
        
        return value;
    }
}
/**
 * the data class
 *
 */
class FoodInfo {
    private String name;
    private int cal;
    private int price;
    
    public FoodInfo() {
        
    }
    public FoodInfo(String name, int cal, int price) {
        this.name = name;
        this.cal = cal;
        this.price = price;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setCal(int cal) {
        this.cal = cal;
    }
    public int getCal() {
        return cal;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public int getPrice() {
        return price;
    }
}


template.jrxml

This is the human readable xml file for design the report template, run InfoResource.java as java application will compile it to template file template.jasper

<?xml version="1.0"?>
<!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
 
<jasperReport name="report1">
    <!-- parameters are from test.zul --> 
    <parameter name="reportTitle" class="java.lang.String"/>
    <parameter name="author" class="java.lang.String"/>
    <parameter name="startDate" class="java.lang.String"/>
    <parameter name="image" class="java.io.File"/>
 
     <parameter name="C1" class="java.lang.String">
        <defaultValueExpression>
            new java.lang.String("")
        </defaultValueExpression>
    </parameter>
 
    <parameter name="C2" class="java.lang.String">
        <defaultValueExpression>
            new java.lang.String("")
        </defaultValueExpression>
    </parameter>
 
    <parameter name="C3" class="java.lang.String">
        <defaultValueExpression>
            new java.lang.String("")
        </defaultValueExpression>
    </parameter>
 
     <!-- define fields -->
    <field name="product_name" class="java.lang.String"/>
    <field name="cal" class="java.lang.Integer"/>
    <field name="price" class="java.lang.Integer"/>
 
    <title>
        <band height="120">
            <textField>
                <reportElement x="0" y="0" width="225" height="45"/>
                <textElement textAlignment="Center">
                    <font size="18"/>
                </textElement>
                <textFieldExpression class="java.lang.String">
                    <![CDATA[$P{reportTitle}]]>
                </textFieldExpression>
            </textField>
            <textField>
                <reportElement x="225" y="0" width="225" height="30"/>
                <textElement textAlignment="Center"/>
                <textFieldExpression class="java.lang.String">
                    <![CDATA["Run by: " + $P{author}
                        + " on " + $P{startDate}]]>
                </textFieldExpression>
            </textField>
            <image hyperlinkType="None">  
                <reportElement x="0" y="50" width="50" height="50"/>  
                <imageExpression class="java.io.File">
                    <![CDATA[$P{image}]]>  
                </imageExpression>
            </image>  
        </band>
    </title>
 
 
    <columnHeader>
        <band height="15">

            <textField>
                <reportElement x="0" y="0" width="150" height="15"/>
                <box>
                    <pen lineWidth="2" lineColor="#000000"/>
                    <topPen lineWidth="2" lineColor="#000000"/>
                    <leftPen lineWidth="2" lineColor="#000000"/>
                    <bottomPen lineWidth="0" lineColor="#000000"/>
                    <rightPen lineWidth="0" lineColor="#000000"/>
                </box>
                <textElement textAlignment="Center" />
                <textFieldExpression class="java.lang.String">
                    <![CDATA[$P{C1}]]>
                </textFieldExpression>
            </textField>
 
            <textField>
                <reportElement x="150" y="0" width="150" height="15"/>
                <box>
                    <pen lineWidth="2" lineColor="#000000"/>
                    <topPen lineWidth="2" lineColor="#000000"/>
                    <leftPen lineWidth="0" lineColor="#000000"/>
                    <bottomPen lineWidth="0" lineColor="#000000"/>
                    <rightPen lineWidth="0" lineColor="#000000"/>
                </box>
                <textElement textAlignment="Center" />
              <textFieldExpression class="java.lang.String">
                    <![CDATA[$P{C2}]]>
                </textFieldExpression>
            </textField>
 
            <textField>
                <reportElement x="300" y="0" width="150" height="15"/>
                <box>
                    <pen lineWidth="2" lineColor="#000000"/>
                    <topPen lineWidth="2" lineColor="#000000"/>
                    <leftPen lineWidth="0" lineColor="#000000"/>
                    <bottomPen lineWidth="0" lineColor="#000000"/>
                    <rightPen lineWidth="2" lineColor="#000000"/>
                </box>
                <textElement textAlignment="Center" />
              <textFieldExpression class="java.lang.String">
                    <![CDATA[$P{C3}]]>
                </textFieldExpression>
            </textField>
 
            </band>
    </columnHeader>
 
    <!-- output datas, for more details, please refer to the official document -->
    <detail>
        <band height="15">
            <textField>
                <reportElement x="0" y="0" width="150" height="15" mode="Opaque" forecolor="#ffffff" backcolor="#FF0000"/>
                <box>
                    <pen lineWidth="2" lineColor="#000000"/>
                    <topPen lineWidth="2" lineColor="#000000"/>
                    <leftPen lineWidth="2" lineColor="#000000"/>
                    <bottomPen lineWidth="2" lineColor="#000000"/>
                    <rightPen lineWidth="2" lineColor="#000000"/>
                </box>
                <textElement textAlignment="Center" />
                <textFieldExpression class="java.lang.String">
                    <![CDATA[$F{product_name}]]>
                </textFieldExpression>
            </textField>
 
            <textField>
                <reportElement x="150" y="0" width="150" height="15" mode="Opaque" forecolor="#ffffff" backcolor="#FF0000"/>
                <box>
                    <pen lineWidth="2" lineColor="#000000"/>
                    <topPen lineWidth="2" lineColor="#000000"/>
                    <leftPen lineWidth="2" lineColor="#000000"/>
                    <bottomPen lineWidth="2" lineColor="#000000"/>
                    <rightPen lineWidth="2" lineColor="#000000"/>
                </box>
                <textElement textAlignment="Center" />
                <textFieldExpression class="java.lang.Integer">
                    <![CDATA[$F{cal}]]>
                </textFieldExpression>
            </textField>
 
            <textField>
                <reportElement x="300" y="0" width="150" height="15" mode="Opaque" forecolor="#ffffff" backcolor="#FF0000"/>
                <box>
                    <pen lineWidth="2" lineColor="#000000"/>
                    <topPen lineWidth="2" lineColor="#000000"/>
                    <leftPen lineWidth="2" lineColor="#000000"/>
                    <bottomPen lineWidth="2" lineColor="#000000"/>
                    <rightPen lineWidth="2" lineColor="#000000"/>
                </box> 
                <textElement textAlignment="Center" />
                <textFieldExpression class="java.lang.Integer">
                    <![CDATA[$F{price}]]>
                </textFieldExpression>
            </textField>
 
        </band>
    </detail>
 
</jasperReport> 


test.zul

The zul page for report generation

<zk>
    <vbox>
        <hbox>
            <!-- choose the file type for export report -->
            Choose a File Type :
            <listbox id="format" mold="select" >
                <listitem label="PDF" value="pdf" selected="true" />
                <listitem label="HTML" value="html" />
                <listitem label="Word (RTF)" value="rtf" />
                <listitem label="Excel" value="xls" />
                <listitem label="Excel (JXL)" value="jxl" />
                <listitem label="CSV" value="csv" />
                <listitem label="OpenOffice (ODT)" value="odt" unless="false" />
            </listbox>
            <button label="Get Report">
                <attribute name="onClick">
                    String title = titleValue.getValue();
                    String author = authorValue.getValue();
                    Date date = new Date();
                    showReport(title, author, date);
                </attribute>
            </button>
        </hbox>
        <hbox>
            <!-- input field to set title and author param -->
            Input Title: <textbox id="titleValue" />
            Input Author: <textbox id="authorValue" />
        </hbox>
        <hbox>
            <radiogroup id="rgroup">
                <hlayout>
                    <!-- for choose image file using in report -->
                    <radio label="circle" value="testimg.png" selected="true"/>
                    <radio label="cube" value="testimg2.png"/>
                </hlayout>
            </radiogroup>
        </hbox>
        <!-- the report component, used to generate report -->
        <jasperreport id="report" width="1024px" height="768px" />
    </vbox>
    <zscript><![CDATA[
        import test.report.InfoResource;
        import java.io.*;
        
        void showReport(String title, String author, Date date) {
            String realPath = Executions.getCurrent().getDesktop().getSession().getWebApp().getRealPath("/");
            File img = new File(realPath+File.separator+"WEB-INF"+File.separator+"images"+File.separator+rgroup.getSelectedItem().getValue());
            //Preparing parameters
            Map parameters = new HashMap();
            
            // set parameters for generate report
            parameters.put("reportTitle", title);
            parameters.put("author", author);
            parameters.put("startDate", date.toString());
            parameters.put("image", img);
            parameters.put("C1", "product");
            parameters.put("C2", "total cal");
            parameters.put("C3", "product price");

            // get report template
            report.setSrc("/WEB-INF/template/template.jasper");
            // set params
            report.setParameters(parameters);
            // set data (InfoResource.java)
            report.setDatasource(new InfoResource());
            // set report type (pdf, xls, ...)
            report.setType((String) format.getSelectedItem().getValue());
        }
        ]]>
    </zscript>
</zk>


The Result

view demo online
http://screencast.com/t/3aK8Kb2BTU

Related Post

Create a Report with ZK using iReport and JasperReports
http://books.zkoss.org/wiki/Small_Talks/2012/April/Create_a_Report_with_ZK_using_iReport_and_JasperReports

References

ZK Component Reference/Diagrams and Reports/Jasperreport
http://books.zkoss.org/wiki/ZK_Component_Reference/Diagrams_and_Reports/Jasperreport

Jasperreports tutorial
http://community.jaspersoft.com/wiki/jasperreports-library-tutorial

Downloads

full project
https://github.com/benbai123/ZK_Practice/tree/master/Components/projects/Integrated_Components/jasperreportTest

demo flash
https://github.com/benbai123/ZK_Practice/blob/master/Components/demos/Integrated_Components/jasper_report_test.swf

2 comments:

  1. Hi Benbai

    Thank you very much. Related to Jasper report, i need your suggestion please. This is my email id
    vbsenthilinnet@gmail.com

    Can you please send me a test email to discuss?

    ReplyDelete
    Replies
    1. Hi Senthil,

      I'm sorry but I am not familiar with Jasper Report, I'd suggest post your questions on ZK/JasperReport forum if needed.

      By the way, I do not like to use email since it is full-filled with tasks/spams and will let me overlook something easily, contact more people with it will make it worse.

      Delete