Sunday, January 5, 2014

ADF integration with Jasper Report

In this post i am just posting a few important steps and code snippet which can be helpful to integrate with Jasper Reports for generating a pdf or an excel.


You need add the following jars from /modules/ext folder of Jasper Reports in your ADF project(fonts related jar need to be added if you are using some specific fonts in your jrxml):

Make sure to add above jars from Add Jar/Directory and not through Add Library, otherwise you will get the following error:
<ActionListenerImpl> <processAction> java.lang.ClassCircularityError: net/sf/jasperreports/engine/JRException
javax.faces.el.EvaluationException: java.lang.ClassCircularityError: net/sf/jasperreports/engine/JRException
at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:51)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent$1.run(ContextSwitchingComponent.java:92)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent._processPhase(ContextSwitchingComponent.java:361)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent.broadcast(ContextSwitchingComponent.java:96)
at oracle.adf.view.rich.component.fragment.UIXInclude.broadcast(UIXInclude.java:103)

----------------------------------------------------------------------------------------------------------
// params contains key value pairs for all the parameters to be passed to jasper report
// conn - db connection
// jrxmlPath - path where jrxml is placed. Example - windows : "C:\\Jasper Reports\\reportForm.jrxml "
                                                                               unix : /d01/oracle/DEV/WC/JasperReports/
// reportType - pdf or excel

  public static byte[] generateReport(HashMap params, Connection conn, String jrxmlPath, String reportType)
    throws FileNotFoundException, JRException, IOException, URISyntaxException
  {

    InputStream input =
      new FileInputStream(new File(jrxmlPath));

    JasperDesign design = JRXmlLoader.load(input);
    JasperReport report = JasperCompileManager.compileReport(design);
    JasperPrint jasperPrint =
      JasperFillManager.fillReport(report, params, conn);

    ByteArrayOutputStream byteArrayOutputStream =
      new ByteArrayOutputStream();
    if ("pdf".equals(reportType))
    {
      JasperExportManager.exportReportToPdfStream(jasperPrint, byteArrayOutputStream);
     }
    
    else
    {
      // Generating an excel
      JRXlsExporter exporter = new JRXlsExporter();
      exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
      exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, byteArrayOutputStream);
      exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE); 
      exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE); 
    exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE); 
      exporter.exportReport();
    }
    byte[] data = null;
    if(byteArrayOutputStream != null)
    {
      data = byteArrayOutputStream.toByteArray();    
    }
    return data;
  }

----------------------------------------------------------------------------------------------------------
For passing jrxmlPath I am saving the same in DB and for jdeveloper I am hardcoding like this:

  public static String getJasperRootPath()
  {
    if(isCodeRunningOnJdev())
    {
      return "C:\\Jasper Reports\\";
    }
// get from DB or property file
    return (String)getConfigRow().getAttribute("JasperRootPath");
  }

----------------------------------------------------------------------------------------------------------
// this method tells us if we are running on JDEV or on SERVER
  public static boolean isCodeRunningOnJdev()
  {
    boolean b = false;
    try
    {
      //this line should throw headless exception on server
      //due to opmn.xml configuration for oc4j node.
      //and would work fine in local jdev
      Toolkit.getDefaultToolkit().getScreenSize();
      b = true;
    }
    catch (Exception e)
    {
      //Code is running on Server
    }
    return b;
  }
----------------------------------------------------------------------------------------------------------

Using parameters in query string in jrxml:
a.   <queryString>
<![CDATA[select FIRST_NAME,
Application_id,
LAST_NAME  ,
EMAIL  ,
mobile_number   ,
alternate_mobile_number  ,
to_char(submission_date,'DD-MON-YYYY hh:mi AM') submission_date
from xx_table
WHERE Application_id=$P{PARAM1}]]>
</queryString>

b.  <queryString>
<![CDATA[select
xyz.company_name,
xyz.first_name,
xyz.last_name,
xyz.mobile_number,
xyz.email,
where xyz.Status='Y'
and $P!{PARAM1}
]]>
</queryString>

Note : !(exclamation sign in $P!{PARAM1}).
You can even pass order by clause also in your param1 when calling from adf.

Whenever you make any change in MAIN jrxml, you can just copy it in server and no need of compiling it or restarting the server. In the code itself we are compiling it and this is an advantage if jrxml is not part of project.
JasperReport report = JasperCompileManager.compileReport(design);

--------------------------------------------------------------------------------------------------------


I will keep on editing this post to include more information on ADF-Jasper Report integration.

Hope this is helpful.

Regards,
Deepak

6 comments:

  1. net.sf.jasperreports.engine.JRException: java.io.UTFDataFormatException: Invalid UTF8 encoding.

    ReplyDelete
    Replies
    1. Which version of JasperReport jar are you using in ADF project?
      What is the version of iReport tool?

      Delete
  2. Very Nice Example. i tried it out but i am getting this
    Exception:java.io.UTFDataFormatException: Invalid UTF8 encoding.
    I am using iReport Designer 4.0.1 and Jdeveloper 11.1.1.7.0

    ReplyDelete
    Replies
    1. Please make sure you are using correct version of libraries in your project.
      As far as I remember I also got the same issue with 4.0.1, try using 3.7.0 and you will not get this issue.

      Delete
  3. Hello I have implemented a similar solution but when i press the print button in my adf page nothing is happening. No errors / No report. This is happening on a wls 12c server. When i run it from integrated WLS in JDEV i see that is trying to open something but it returns imeediate to my initial adf page. What am i doing wrong ?

    ReplyDelete
  4. how can i call jasper report from adf fragment ".jsff"

    ReplyDelete