Showing posts with label iReport. Show all posts
Showing posts with label iReport. Show all posts

Wednesday, 12 September 2012

Integrate Chart Image into Jasper Report Part - 2

In my previous post we discussed how to Integrate the Charts into Jasper Reports using JFreeChart API in Jasper Report. In this post there is another way to embeds the charts into Jasper Reports. This method, we need to generate/create the chart using any 3rd party Java Lib and convert into Image Object or stored into File-system, then just insert the Image into Jasper Report. here no need to use chart functionality in Jasper Report. because these chart are limited functionality.


Steps:
  1. Create the chart using any Java libraries
  2. Convert the Chart into BufferedImage or Stored into files
  3. pass the Image into Jasper Report.

1. Create the chart using any Java libraries
     In this step we going to create the chart. here i m using jopenchart Java library to create the chart. In their website tutorial section contain some sample codes. so i used these codes. and download the jopenchart lib from here.

2. Convert the chart into BufferedImage or Stored into files
    In jopenchart have the in-build function for store chart into the file.
ChartEncoder.createPNG(new FileOutputStream(System.getProperty("user.home") + "/chat.png"), c);
and if u want into in-memory Image object then use render() method.
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
DefaultChart chart = ....;
Graphics2D gd=bi.createGraphics();
chart.render(gd);

In above code we create empty BufferedImage object. the get the Graphics2D object from the BufferedImage and pass the Graphics2D into chart render() method. so when render() method is called, the chart is write into BufferedImage object.

3. Pass the Image into Jasper Report
        We need to create the Jasper Report. this time we are not using chart function in Jasper reports. we using Image component of jasperreport. We have 2 options are there, pass the Image Object or Pass the Path String object where image is stored in File-system. here first i m using Image object.

we use parameter to pass into jasper report. so first create the new Parameter in Jasper Report and named "chartImage" and Parameter Class "java.lang.Object".  drag the Image Component and set the properties. Image Expression and Expression Class like
               Image Expression == >  $P{chartImage}
               Expression Class  == > java.awt.Image



If we use stored Image File then change the Parameter class to java.lang.String and Image Expression Class to java.lang.String.

here Image Expression class is decided the Jasper Report. how we add the Image. If u put "java.awt.Image" as a Expression class then we are passing the Image object. and jasper report can understand. If u mention "java.lang.String" then we pass as String that pointing to Image file. (png,jpg,gif,..).

Code:
DemoBean.java
@ManagedBean
@SessionScoped
public class DemoBean {

    int width = 640;
    int height = 480;
    BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    public DemoBean() {
        int[] quadr = {0, 1, 4, 9, 16, 25, 36};
        int[] exp = {1, 2, 4, 8, 16, 32, 64};
        double[] columns = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0};

        // Creating a data set array
        DefaultDataSet[] ds = new DefaultDataSet[3];

        // Filling all DataSets
        ds[0] = new DefaultDataSet(ChartUtilities.transformArray(new int[]{0, 6}),
                ChartUtilities.transformArray(new double[]{0.0, 6.0}),
                CoordSystem.FIRST_YAXIS,
                "Linear Growth");

        ds[1] = new DefaultDataSet(ChartUtilities.transformArray(quadr),
                ChartUtilities.transformArray(columns),
                CoordSystem.FIRST_YAXIS,
                "Quadratic Growth");

        ds[2] = new DefaultDataSet(ChartUtilities.transformArray(exp),
                ChartUtilities.transformArray(columns),
                CoordSystem.FIRST_YAXIS,
                "Exponential Growth");

        String title = "Growth Factor Comparison";



        DefaultChartDataModel data = new DefaultChartDataModel(ds);

        data.setAutoScale(true);

        DefaultChart c = new DefaultChart(data, title, DefaultChart.LINEAR_X_LINEAR_Y);

          c.addChartRenderer(new LineChartRenderer(c.getCoordSystem(),data), 1);

        c.setBounds(new Rectangle(0, 0, width, height));
        Graphics2D gd=bi.createGraphics();
        c.render(gd);

//      /*  if ur using Image file then use these code */
//        try {
//            ChartEncoder.createPNG(new FileOutputStream(System.getProperty("user.home") + "/chart.png"), c);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }


    }

    public String pdf() throws JRException, IOException {

       
        String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reports/Charts.jasper");

        Map parameter = new HashMap();
        parameter.put("chartImage", bi);

        JasperPrint jasperPrint = JasperFillManager.fillReport(reportPath, parameter, new JREmptyDataSource(1));
        HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
        httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.pdf");
        ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
        JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
        FacesContext.getCurrentInstance().responseComplete();

        return null;
    }
}



Download the Sample Project from my  GitHub


Check the screen-cast for better understanding.

Screen cast:

Wednesday, 5 September 2012

Integrate Charts in Jasper Reports +JSF 2.0

In this post we will walk through how to integrate Charts (JFreeChart) into Jasper Report framework. JasperReports is the world's most popular open source reporting engine. It is entirely written in Java and it is able to use data coming from any kind of data source and produce pixel-perfect documents that can be viewed, printed or exported in a variety of document formats including HTML, PDF, Xlsx, Docx, Pptx, Odf

Check my Introduction to Jasper Reports and Sub-report with jasper Report posts.

2-ways to Integrate the Charts/Graphs into Jasper Reports
  1. Use JFreeChart API inside Jasper Report to generate the Charts while generating reports
  2. Use any 3rd party Java Libraries to create the chart and stored in In-memory Image object (or) stored in file. then pass the Image/file to Jasper Report. then embed the Image into Report. (check here)
In this post we going to use 1st option. In Jasper Report use JFreeChart Components to make charts. In my next post we will see the 2nd way to generate the charts in reports.

I ll create one sample application (Progress Report) to demonstrate the Integrate the charts in reports.

I have Student Bean contain name, roll No, image and List of Semester paper beans. In Semester paper bean contain name of the paper and mark(score).

Student.java
import java.util.List;

/**
 *
 * @author ramki
 */
public class Student {
    private String name;
    private String rollNo;
    private String imagePath;
    private List listOfSemesterPaper;

    // getters and setters
}

SemesterPaper.java
public class SemesterPaper {
    
    private String name;
    private double mark;

   
    public SemesterPaper(String name, double mark) {
        this.name = name;
        this.mark = mark;
    }

    // getters and setters
    
}


Create the Report
    we can use either iReport Standalone version or Jasper report Net-beans plugins to create the jasper Reports.

Create empty reports and create the fields and these fields are match with Student bean property variables. here name,rollNo and imagePath are String. so no need to change the data type of field. but listOfSemesterPaper is List. so change the data type of the field to List.

then drag Image component and static text component for making general report like this
here name and rollNo fields are dragged into report canvas, then drag the Image component and change the expression of Image component to imagePath field. Now we ready for bring the Chart component. But chart data are stored in listOfSemesterPaper field. Its List. So we can't use directly. so we going to create sub data set from main data set. so create sub dataset named "ChartDataset". and In sub data set create another 2 fields match with SemesterPaper bean. here name is String and mark is double.

Now drag the chart and choose the chart type. here i chosen Bar chart. its poped up the wizard.  we need to choose Data set. here we need to choose "ChartDataset" sub data set, which one we created. then select the Category and Value property of Charts. here name is category and mark is value. (see the screenshot)



and final step is we need to explicitly mention how main data set is divied into sub data set. In sub data set "ChartDataset" is take value of listOfSemesterPaper field. this fields is List. so we need to wrap into JRBeanCollectionDataSource.

that's it. now compile the report and generate the .jasper format. then integrate into Netbeans project.


DemoBean.java
@ManagedBean
@SessionScoped
public class DemoBean {

    private List listOfStudent;

    public DemoBean() {
        listOfStudent = new ArrayList();

        Student student = new Student();
        student.setName("Ramki");
        student.setRollNo("02CS24");
        student.setImagePath("C:\\Users\\ramki\\Downloads\\ramki.jpg");

        List listOfSemsterPaper = new ArrayList();
        listOfSemsterPaper.add(new SemesterPaper("S/W Engg", 50.6));
        listOfSemsterPaper.add(new SemesterPaper("Java", 88.6));
        listOfSemsterPaper.add(new SemesterPaper("Data Struct", 66.6));
        listOfSemsterPaper.add(new SemesterPaper("Algorithm", 77.6));
        listOfSemsterPaper.add(new SemesterPaper("Lab 1", 90.6));
        listOfSemsterPaper.add(new SemesterPaper("Lab 2", 99.6));

        student.setListOfSemsterPaper(listOfSemsterPaper);

        listOfStudent.add(student);


    }

    public String pdf() throws JRException, IOException {
        JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(listOfStudent);
        String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reports/chartReports.jasper");
        JasperPrint jasperPrint = JasperFillManager.fillReport(reportPath, new HashMap(), beanCollectionDataSource);
        HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
        httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.pdf");
        ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
        JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
        FacesContext.getCurrentInstance().responseComplete();
        return null;
    }
}


index.xhtml
    
        Facelet Title
    
    
        
            Generating Report : 
        
    

Download the Sample Project from my  GitHub

Watch in HD

Comments are Welcomed

Thursday, 10 November 2011

JSF + JPA + JasperReports (iReport) Part 1

Hi in this post we will see the overview of JasperReports and how to integrate into JSF application. JasperReports is the world's most popular open source reporting engine. It is entirely written in Java and it is able to use data coming from any kind of data source and produce pixel-perfect documents that can be viewed, printed or exported in a variety of document formats including HTML, PDF, Excel, OpenOffice and Word.

 In Primeface library also use this JasperReports to generate the PDF, CSV and DOC formats with single line of code. see here. but its not flexible and we cant change template. so here we see the how to use JasperReports for create the template and integrate  JSF 2.0.

We are using iReport tool for crating template.

Download JasperReports and iReport

  • Jasper Reports download from here. This zip contain jasper library and its dependencies and lots sample codes.
  • iReport download  from here
Now create the simple JSF Application to retrieve the data from database using JPA, then create the template using iReport and then integrate into JSF application.

JSF+JPA
  Java Persistence API is standard way to access the all ORM (Object Relational Mapping) tools like Hibernate, EclipseLink, TopLink,.. . These tools are internally use JDBC to access the database.

the Heart of JPA is consist of two parts

  • persistence.xml - Its xml file describe the persistence provider (ORM provider) and connection information like database URL, username and password. or data source.
  • Entity Classes - Its normal POJO class for each table in underlying table. This class is annotated with @Entity and some annotation provided by JPA. Its way to express and map the property in the class into table in the DB. 
These entity class are  manually we can create or using IDE tools like Net beans IDE provide "Entity Classes From Database" option to auto generate the Entity Classes. (See video in below)

Once these entity classes are created then we need to create CRUD methods to wrapping these entities for ease of use. These kind of classes also auto generate from "Session Beans from Entity Classes" option.

 Here we using GlassFish Server 3. Its supports EJB 3.1. 
Now we create the JSF page to display the entity classes in table structure and provide buttons for export into variety of formats.


index.xhtml

        Facelet Title
    
    
        
        
            
             
              
               
               
        
        
            
                
                    User Name
                
                #{user.userId}
            
            
            
                
                    Password
                
                #{user.password}
            
        
    


Jasper Reports
Once sample JSF application is completed then we going to integrate Jasper Reports. 
First, include all necessary lib into our application. We already download the jasper library zip file. Extract this file they have lots of folder. one for dist folder contain main jasperreports-4.1.3.jar file and lib folder contain all necessary dependencies. see the requirements of jasper reports from here.

This is flow diagram of JasperReports. 

Jasper Report Flow

Here we use iReport tool to generate the JRXML template. this file is pure xml file to describe the layout and place-holders. then we need to compile into jasper file. its binary format. this compilation process we can do in 2 ways. 
  1. Using iReport to compile the jrxml file into jasper
  2. Using JasperReport API we can do through programme.
This is the code snippet compile the jrxml file into jasper file
JasperCompileManager.compileReportToFile("report.jrxml", "report.jasper");

or we can use iReport to compile

now compilation is finished. data is also ready. here data is java beans (entity beans) . This entity beans can't use directly. we wrap into one more class JRBeanCollectionDataSource then using JasperFillManager we generate JRPRINT object.

code:
JRBeanCollectionDataSource beanCollectionDataSource=new JRBeanCollectionDataSource(listOfUser);
JasperPrint jasperPrint=JasperFillManager.fillReport("report.jasper", new HashMap(),beanCollectionDataSource);

once JasperPrint is ready then we export using JasperExportManager
JasperExportManager.exportReportToPdfFile(jasperPrint, "report.pdf");

For exporting into docx, xlsx, odt, ods, pptx formats we should use JRDocxExporter, JRXlsxExporter, JROdtExporter, JROdsExporter, JRPptxExporter 
and one more thing we don't want to store the exported format into file system. we need to send these formats to client via stream.
Code:
HttpServletResponse httpServletResponse=(HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.docx");
ServletOutputStream servletOutputStream=httpServletResponse.getOutputStream();
JRDocxExporter docxExporter=new JRDocxExporter();
docxExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
docxExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, servletOutputStream);
docxExporter.exportReport();
FacesContext.getCurrentInstance().responseComplete();


here we get the OutputStream via FacesContext.



You can download this complete example from GitHub (or) Google Code

DemoBean.xml
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.ramki.jsf;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.oasis.JROdtExporter;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporterParameter;
import net.sf.jasperreports.engine.export.ooxml.JRPptxExporter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import org.ramki.entity.User;
import org.ramki.session.UserFacade;

/**
 *
 * @author ramki
 */
@ManagedBean
@SessionScoped
public class DemoBean {
    private List listOfUser;

    @EJB UserFacade userFacade;
    
    public List getListOfUser() {
        listOfUser=userFacade.findAll();
        return listOfUser;
    }

    public void setListOfUser(List listOfUser) {
        this.listOfUser = listOfUser;
    }
    JasperPrint jasperPrint;
    public void init() throws JRException{
        JRBeanCollectionDataSource beanCollectionDataSource=new JRBeanCollectionDataSource(listOfUser);
String  reportPath=  FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reports/report.jasper");        jasperPrint=JasperFillManager.fillReport(reportPath, new HashMap(),beanCollectionDataSource);
    }
    
   public void PDF(ActionEvent actionEvent) throws JRException, IOException{
       init();
       HttpServletResponse httpServletResponse=(HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
      httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.pdf");
       ServletOutputStream servletOutputStream=httpServletResponse.getOutputStream();
       JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
       FacesContext.getCurrentInstance().responseComplete();
       
       
   }
    public void DOCX(ActionEvent actionEvent) throws JRException, IOException{
        init();
       HttpServletResponse httpServletResponse=(HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
       httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.docx");
       ServletOutputStream servletOutputStream=httpServletResponse.getOutputStream();
       JRDocxExporter docxExporter=new JRDocxExporter();
       docxExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
       docxExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, servletOutputStream);
       docxExporter.exportReport();
       FacesContext.getCurrentInstance().responseComplete();
   }
     public void XLSX(ActionEvent actionEvent) throws JRException, IOException{
        init();
       HttpServletResponse httpServletResponse=(HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
      httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.xlsx");
       ServletOutputStream servletOutputStream=httpServletResponse.getOutputStream();
       JRXlsxExporter docxExporter=new JRXlsxExporter();
       docxExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
       docxExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, servletOutputStream);
       docxExporter.exportReport();
       FacesContext.getCurrentInstance().responseComplete();
   }
      public void ODT(ActionEvent actionEvent) throws JRException, IOException{
       init();
       HttpServletResponse httpServletResponse=(HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
      httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.odt");
       ServletOutputStream servletOutputStream=httpServletResponse.getOutputStream();
       JROdtExporter docxExporter=new JROdtExporter();
       docxExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
       docxExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, servletOutputStream);
       docxExporter.exportReport();
       FacesContext.getCurrentInstance().responseComplete();
   }
       public void PPT(ActionEvent actionEvent) throws JRException, IOException{
       init();
       HttpServletResponse httpServletResponse=(HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
      httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.pptx");
       ServletOutputStream servletOutputStream=httpServletResponse.getOutputStream();
       JRPptxExporter docxExporter=new JRPptxExporter();
       docxExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
       docxExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, servletOutputStream);
       docxExporter.exportReport();
       FacesContext.getCurrentInstance().responseComplete();
   }
    
}


Update (02/01/2012): 
mourad mourad mentioned that report’s absolute path is hardcoded like C:\\UsersramkiDesktopreport.jasper". This doesn't work once you deploy your application in another application server.
Yes that's correct. now i fix it.. i used for simplicity purpose.
I try to used getResourceAsStream() method. But it wont work. the reason is our report needs some supporting files like images. If ur report contain no image then u can use getResourceAsStream() method.
So here i want the path of the report jasper file. Then this report engine get the images from that path.

String  reportPath=  FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reports/report.jasper");
jasperPrint=JasperFillManager.fillReport(reportPath, new HashMap(),beanCollectionDataSource); 


Update (22/02/2012): 
            DrAhmedJava commented that i noticed that you have an exception - getOutputStream() has already been called for this response- in your output, and it also happened to me. and i want to share the solution: (Thanks for sharing solution, i updated the code)
                    The idea is that after the pdf() method writes the pdf to http response, the jsf servlet itself tries to reopen the response to write the html rendered from rendering stage of the life cycle, so the solution is to tell the jsf servlet that the response is complete and to skip the rest of life cycle: 
JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream); 
FacesContext.getCurrentInstance().responseComplete(); 


Update : For sub reports and Date Objects check Part 2 of this Series 


Watch the video in HD



Comments are Welcomed
Related Posts Plugin for WordPress, Blogger...