Sunday, December 9, 2012

Using Jasper Report In ADF Application (Step-by-Step)

In my previous post  http://sameh-nassar.blogspot.com/2009/10/using-jasper-reports-with-jdeveloper.html I explain how to use Jasper Report but because of many people send me many requests for explain this topic in more detail so I will explain it in step by step.

our example will make application with one screen this screen has a table of employees you should select an employee and send the selected employee id to jasper report to print the selected employee data.

Before we begin be sure of:

1- You download iReport-4.0.1 (you can get it from http://sourceforge.net/projects/ireport/files/iReport/iReport-4.0.1/) I download iReport-4.0.1-windows-installer.exe.

2- You have database has hr schema.

3- Setup JDeveloper 11g (any release).

Now we can begin ......

Step 1:

Setup iReport-4.0.1
Step 2:
Open JDeveloper and make new ADF Application (name it for example JasperApplication)

Step 3:

Connect your application to your database HR Schema by right click in your Model application ---> new ---> ADF Business Components ---> Business Components From Table
Add your connection and test the connection

Add one Entity Objects (Employees)
Add one Updatable View Objects
Then press finish, your application should be like this
Step 4:
Create new jspx page (name it for example employees.jspx)
In your ViewController project right click on Web Content folder then new --->JSF ---> JSF Page

From the Data Controls drag EmployeesView1 to your page as an ADF Read-only Table


From Row Selection Select Single Row
Add a button above a table (text it for example Run Report) and its action point to a method in a back bean (for example Back bean name is JasperBean.java)


To get the selected employee id:
    DCIteratorBinding empIter = (DCIteratorBinding) getBindings().get("EmployeesView1Iterator");
    String empId = empIter.getCurrentRow().getAttribute("EmployeeId").toString();

where EmployeesView1Iterator is the iterator name in the page definition and EmployeeId is the attribute name in the EmployeesView.

now we should pass the selected employee Id to jasper report so, you should make a map and set the parameter like
    Map m = new HashMap();
    m.put("employeeId", empId);// employeeId is a jasper parameter name

then you should call the jasper report like this method
 runReport("empReport.jasper", m);

where runReport is the method take jasper report name (empReport.jasper) and the map which hold the parameter

write this code in your JasperBean.java

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



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

After you write this code you will find Jasper library missing

to get jasper libraries goto the folder which you setup iReport for example in this path
C:\Program Files (x86)\Jaspersoft\iReport-4.0.1\ireport\modules\ext
and get these libraries:
1- iText-2.1.7.jar
2- jasperreports-4.0.1.jar
3- jasperreports-fonts-4.0.1.jar

add this libraries to your ViewController project ---> Right click on the project ---> Project Properties--->Libraries And Classpath ---> Add JAR/Directory

Now your code should have no error

Now my Back bean code is :
----------------------------------------------------------------------------------------------------------------------



--------------------------------------------------------------------------------------------------------------------------
Now depending on my previous code we should make a report the name of this report should be "empReport" and has one parameter "employeeId"

Step 5:

Open iReport and make a connection to hr database but first ..... iReport has not oracle database driver so you use oracle database you should first add a ojdbc jar file to the classpath of iReport.

you can get ojdbc jar file in your middleware home like:
C:\Oracle\Middleware\wlserver_10.3\server\lib and search for ojdbc6.jar

In iReport goto Tools---> Options ---> Classpath and add ojdbc6.jar
Now make a new connection to hr schema
Now from File ---> New and make new Report
Choose any template or make it blank then press "Launch Report Wizard"

Write report name "empReport" and under your web content folder in ViewController project make new folder "reports" and save the report on this path


Press on Design query button and select your schema then drag Employees table
then press Ok you will find the report query will generated then press Next and shuttle the field you want to displayed in your report
Then press next then finish. You will find you report generated.
Goto the report query as shown:

and make new Parameter "employeeId"
add where clause to the query like:
WHERE EMPLOYEES."EMPLOYEE_ID"=to_number($P{employeeId})

Now you can preview your report by pressing on "Preview" button and enter for example employeeId = 200


Now compile your report to generate .jasper file in your application
If you goto your application you should something like this:
before you run be sure of two things:
1- any picture you use in jasper should be in the class path
2- You should define datasource in your weblogic "as we write in the code datasource is hrDS"


for how you can define data source in weblogic try this http://www.mediafire.com/file/g7odbc06rpad1aa/dataSourceInWeblogic.doc/file

Step 6:
run your application and select any employee then press on "Run Report" button
for example select employee Id= 104 then run report



you can download the application from this link JasperApplication



To open the report in new window:

1- In the .jspx right click on the af:document -->Facets - Document --> Meta Container 
2- Inside f:facet - metaContainer add af:resource with type="javascript" as:


inside af:resource you can add javascript function 

function newWindow()
{
  document.getElementById("f1").target = "_blank;targetfeatures=toolbar=no location=no directories=no menubar=no";
}

where "f1" is the af:form id.

So the structure will be:



To call this function add button or link and inside this link add clientLister as:





85 comments:

  1. Very Nice and easy to understand. thanks for sharing such a nice content.

    ReplyDelete
  2. هذا هو الإبداع الحقيقي في عرض المعلومة
    جزاك الله عنا كل خير

    ReplyDelete
  3. Brother Sameh,

    can you please tell me that I want to develop an Oracle based large scale web application and want to use some reporting it it. Jasper reporting tool is appropriate for the said reporting? I mean, the features grouping, controls etc (like we use in .Net Crystal Report) are available?

    Please reply me here(or if you can personally in my address rsiddiqui@abacusoft.com)

    Jazak ALLAH

    ReplyDelete
    Replies
    1. Hi Rashid,

      I don't work with Crystal Report before but Jasper has grouping, controls, graphs, calling java methods feature and sub-report. We make very large scale applications with complex report using jasper.

      Regards,

      Delete
  4. The Report Integration Framework goes far beyond this:
    http://whitemagicsoftware.com/software/java/rif/

    Read Chapter 15 (free) to see a generic way to integrate JasperReports with ADF: http://whitemagicsoftware.com/books/indispensable/

    The idea is that you can decouple any report framework from the ADF application. The last thing you want to do is couple Oracle Reports, JasperReports, BIRT, or CrystalReports to your application when you don’t need to.

    The Report Integration Framework provides a pluggable system where you can swap out one report engine for another, and not one line of code in the ADF application needs to change.

    ReplyDelete
  5. Dear eng.sameh
    I Follow the steps but the program generate this error
    javax.naming.NameNotFoundException: Unable to resolve 'hrDS'. Resolved ''; remaining name 'hrDS'
    please if u can fixed this issue i'll appreciate

    regards

    ReplyDelete
    Replies
    1. Dear sief,
      this is not an issue, you should define data source in your weblogic with JNDI name hrDS.
      If you run your application in jdeveloper so you should define data source in integrated weblogic. you can connect to the weblogic console like(http://localhost:7101/console) and enter weblogic username and password like(weblogic/weblogic1) and from services menu define generic data sourse with name hrDS.

      Regards

      Delete
  6. Wao great link and perfect guidelines :) @Samah Nassar sir, I have done it completely it works very well ... but I also tried to generate the jasper report by a view which is based of the Parametrized view but it is not working there ....Any suggestion please ?

    ReplyDelete
    Replies
    1. Hi,
      I do understanding what is the meaning of generate the jasper report by a view??

      Jasper report should hold the query internally this view may has a parameter and you can pass this parameter as I explain in this example.
      Regards

      Delete
  7. Hi,
    Can you help me?
    I've trying to generate reports with jasper report but i have this error:
    Caused by: java.lang.NoClassDefFoundError: net/sf/jasperreports/engine/util/JRLoader
    at beans.JasperBean.runReport(JasperBean.java:88)

    The code line is:
    JasperReport template = (JasperReport) JRLoader.loadObject(fs);

    In the runReport method

    Any help?
    Thanks.

    ReplyDelete
    Replies
    1. Hi
      Check the version of ireport which you are use and the libraries you use in your application. Try to use the same version of ireport and the libraries in my example.
      Regards

      Delete
  8. Hi Samesh Sir,

    Please help me with this step.

    2- You should define datasource in your weblogic "as we write in the code datasource is hrDS"

    Can you upload a step-by-step tutorial for this step?

    Thank you in advance,

    Rahul

    ReplyDelete
    Replies
    1. Hi Rahul,

      I make small documentation for how you can define data source in weblogic you can download it from http://www.mediafire.com/view/?g7odbc06rpad1aa

      Regards,

      Delete
  9. Hi Sameh,
    Is it possible to download the pdf to the users OS (maybe using fileDownloadActionListener) as a file or open the pdf in a new browser tab or window and keep the current view of the jspx page?

    Thank you for this useful tutorial.

    ReplyDelete
    Replies




    1. Hi Ali ,
      You don't need to use fileDownloadActionListener you can insert inside button which will run the report af:clientListener which call javascript method to open the report in new window like:

      af:commandButton text="Run Report" id="cb1" action="#{jasper.runReportAction}">
      af:clientListener type="action" method="newWindow"/>
      /af:commandButton>


      and in your jsp page and this javascript method:
      function newWindow()
      {
      document.getElementById("f1").target = "_blank;targetfeatures=toolbar=no location=no directories=no menubar=no";
      }

      Delete
    2. hey Sameh , hope to get replay on my question here ?
      I wanted to open Jasper Report as PDF on new web browser window , so I did your solution above , it works fine , but! the command button turned into disabled after click it , i am sure i am using your servlet , your work around for new Window , do you have any idea ??

      Delete
    3. Hi Sameh
      I need to open pdf report in new window too.
      But i could not use your solution .
      May you explain me more ?
      1- where can i write function newWindow() and how ?
      2- what is "f1" in this line document.getElementById("f1").target ?

      thanks a lot

      Delete
    4. Hi Sara,
      1- in your .jspx after af:document you can add af:resource with type = javascript and inside af:resource you can add javascriptmethod like this:



      function newWindow()
      {
      document.getElementById("f1").target = "_blank;targetfeatures=toolbar=no location=no directories=no menubar=no";
      }


      2- "f1" is the id of af:form like:

      Delete
  10. HiSameh,
    Thank you so much for your clear explanation:)

    Ellerine sağlık ;)
    Betül

    ReplyDelete
  11. Thank you so much...Nicely explained.
    one question. I implemented the open in new window functionality and it is working. but one problem is if one report is opened in a window and without closing it, if I select another employee and generate report, then it gives error. the error is shown in the same window where the first report was shown. Error is "Error 403--Forbidden
    From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:
    10.4.4 403 Forbidden
    The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable."

    ReplyDelete
    Replies
    1. Hi,
      I try your scenario put it work without error. You can send your code in my email to check it.

      Regards,

      Delete
  12. Hi,
    I tried it. But the program is not running as I am clicking on the print button I haven't got any response fro it. I follow all the steps and i am not getting any error also. Can you help me for it.

    Regards
    Saurabh

    ReplyDelete
    Replies
    1. Hi,

      Are you download my application and it is not running? are you sure that you make data source in weblogic?

      Delete
    2. same here...after click on button m not getting any error or report....but in j developer there is null point exception in jasper loader

      Delete
  13. Hi,

    Thank you for such a nice example.
    I just want to know.How I can put my whole table data using this example.

    Kindly reply ASAP
    Thanks in advance

    ReplyDelete
    Replies
    1. Hi,
      What do you mean with whole table? do you mean you want to display all rows of employees in table? if that you can send no parameters and in the jasper report query remove the where clause it will display all rows.

      Regards,

      Delete
  14. جزاك الله الف خير ابداع في الشرح واسلوب العرض وفقك الله لما يحبه ويرضاه

    ReplyDelete
  15. excellent publish, very informative. I wonder why the opposite specialists of this
    sector do not understand this. You must continue
    your writing. I'm confident, you have a huge readers' base
    already!

    Look at my web page ... appetite women experience

    ReplyDelete
  16. hi haw are you thx you for your very good work may i ask you about using .rdf report
    i want adf application example in more details about Using oracle Report (.rdf) In ADF Applicationoracle

    ReplyDelete
    Replies
    1. Hi,

      you can call oracle report from your ADF Application as I post in http://sameh-nassar.blogspot.com/2012/05/call-oracle-reports-from-your-adf.html

      Delete
  17. مايميزك عن القية أنك تشرح بالتفصيل وتذكر كل شيء حتى التفاصيل البديهية. لذلك تستطيع ايصال المعلومة للقارء بشكل سلس.

    شكرا لك.

    ReplyDelete
  18. Hi Sameh
    I have arabic word (field of query) in my report I can see them in report of ireport but when I run my application , the arabic words aren't shown in pdf on browser .
    shall you help me?
    regards

    ReplyDelete
    Replies
    1. Hi,
      Arabic words will not appear if you use fonts from IReport. you sould use arial.ttf font, From IReport you can make font as a jar file hold arial.ttf file and add this jar file in the IReport (If you do not know how to make this jar file I made a jar file you can download this jar file from http://www.mediafire.com/download/48m0ihpazqaihz7/JFonts.jar and add this jar file in the IReport classpath) now select any field from the report (that will display arabic word) and from property change the font to "sdArial" where sdArial is the name that defined inside my jar file

      Delete
    2. Dear Sameh
      Thanks a lot , it works.

      Delete
  19. Thx you I will try Ariel jar and I will told you the result just I want thx you aging for your effort

    ReplyDelete
  20. very nice...quite informative..!!!!..keep posting like this blog..!!!!

    ReplyDelete
  21. Thank you for this tutorial.
    For set up all things to work for me i had to change two things.

    1. getConnection - there is no need to define data JNDI source on WLS.

    private Connection getConnection() throws Exception
    {
    // return getDataSourceConnection("hrDS");// use datasourse in your application

    String amDef = "he.model.AppModule";
    String config = "AppModuleLocal";
    PreparedStatement st = null;

    AppModuleImpl am =(AppModuleImpl) Configuration.createRootApplicationModule(amDef,config);
    st = am.getDBTransaction().createPreparedStatement("select 1 from dual", 0);
    Connection conn = st.getConnection();
    return conn;
    }

    2. add some aditional libraries
    - groovy_all.... jar
    - jcommon ... jar

    ReplyDelete
  22. Hi Sameh :
    what do i write in ireport for any images in ireport evevn it workd?
    I write "my_img.jpg" but in adf it has error .

    ReplyDelete
  23. Dear Nasar, Aslam u Alakum,
    I have followed all the process as you told. Bur find the following error kindly help me.


    Error 500--Internal Server Error

    java.lang.IllegalStateException: strict servlet API: cannot call getWriter() after getOutputStream()
    at weblogic.servlet.internal.ServletResponseImpl.getWriter(ServletResponseImpl.java:307)
    at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:122)
    at com.sun.faces.context.ExternalContextImpl.getResponseOutputWriter(ExternalContextImpl.java:723)
    at javax.faces.context.ExternalContextWrapper.getResponseOutputWriter(ExternalContextWrapper.java:669)
    at javax.faces.context.ExternalContextWrapper.getResponseOutputWriter(ExternalContextWrapper.java:669)

    ReplyDelete
    Replies
    1. Wealekom Aslam,

      you can check the version of IReport and JDeveloper which you are use because sometime the version of the library cause errors. try to use IReport any of version 4

      Delete
    2. Dear Sameh and shahid,
      We can solve this issue without back to old versions of Jasper by modifing the properties of given report to choose from drag box 'Java' instead of 'Groovy' in language property

      Delete
  24. Hi Sameh,

    Thanks for nice article, It was really helpful to get started with basic of Jasper and its integration with ADF. I've followed the demo application and it works perfectly fine for me.

    However when I implemented the same thing in my application it works for first time only. I mean when I click on button to download reports, it works fine. But then it gives the Processing cursor when I bring mouse on the button.

    Any help would be greatly appreciated.

    Thanks

    ReplyDelete
  25. Dear Sameh,

    Aslam u Alakum,

    Thanks for this wonderful post.

    When use new window code in adf page for report . The calling button disabled . Can u please help me

    ReplyDelete
    Replies
    1. Hi,
      you can use af:commandLink with styleClass="x7j p_AFTextOnly" instead of af:commandButton

      Delete
  26. Hello Sameh,
    Although it has been over 2 years since you originally posted this article, it has helped me tremendously. Thank you for taking the time to write this post, and also answer the questions posted by others.

    ReplyDelete
  27. hi samesh

    I followed your post and got succeeded with calling single report from application but when i call a report that has sub reports in it it gives me the error.
    I am using J developer 12 with

    ReplyDelete
    Replies
    1. Hi ,

      I faced the same problem and i solved it by using this lines

      File reportFile = new File(context.getRealPath("/reports/" + repPath));
      conn = getConnection();
      JasperPrint print = JasperFillManager.fillReport(reportFile.getAbsolutePath(), param, conn);
      JasperExportManager.exportReportToPdfStream(print, response.getOutputStream());

      Delete
  28. Hi sameh
    Thank you so much for your clear explanation
    my question

    How can I use following js function inside .jsff page fragment part of taskflow which is rendered as region in jsf page.because there is no af:form in the fragment.


    function newWindow()
    {
    document.getElementById("f1").target = "_blank;targetfeatures=toolbar=no location=no directories=no menubar=no";
    }

    ReplyDelete
    Replies
    1. SHAN,

      Try to add this java script in the .jsf page or in the page template

      Delete
  29. Dear Sameh,

    First of all thank you for the nice post.

    Well, I have a question regarding this post is can I select more than one employee and display their data in table.

    Thank you very much!

    Best Regards,

    ReplyDelete
    Replies
    1. Hi,
      Yes you can. Simply you can select multiple rows from the table and create string as String where= emp_id in (10,20,40); (where 10, 20, 40 is the selected employees id) and send this where as a parameter to the jasper report.
      For how to get selected rows you can check this
      http://sameh-nassar.blogspot.ie/2009/12/use-checkbox-for-selecting-multiple.html

      or

      https://blogs.oracle.com/aramamoo/entry/getting_all_selected_rows_in_adf_table_with_multiple_rows_selection_enabled

      Delete
  30. Thank you very much Sameh!!

    Your help appreciated!

    ReplyDelete
  31. Thank you very much Eng-Sameh
    But I have a problem
    This message appears


    Error 500--Internal Server Error
    From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:
    10.5.1 500 Internal Server Error

    The server encountered an unexpected condition which prevented it from fulfilling the request.

    ReplyDelete
    Replies
    1. Check the server log and see what is the exception, this error is generic you should see the server log to know where this exception happen.

      Delete
  32. Thank you very much Sameh
    But I have a question
    if i want to deploy this application remotely ny ear file what needed

    ReplyDelete
  33. Dear Sameh,

    Thanks for the post it's really helpful.
    My code is stuck on one one thing when i am using commandbutton it works and i can see the report but when i use button as commandbutton is deprecated clicking Run Report just refreshes the page i don't get any error messages although i can see in the code that pdf is generated but not sure why its not displayed and what should i do if i would like to use button in place of commandbutton.

    Thanks

    ReplyDelete
  34. hi samesh i tried this application, but when i am click the button "Run Report" it is in same page only. Please can u help me.


    After deploying my log file looks like..
    Target URL -- http://127.0.0.1:7101/JasperReport-ViewController-context-root/faces/employees.jsf

    ReplyDelete
    Replies
    1. What do you mean by, it is in same page only? do you mean the page is refreshed and no report opened? If yes, is there any error on the server log? If no, try to set "Run Report" button partialSubmit="false" and see

      Delete
    2. I set partialsubmit="false", yet i am facing the same problem

      Delete
    3. Did you resolv the problem?
      i have the same, please Help!

      Delete
    4. If you use region (.jsff) page this way will not work you have to use servlet to call the report. You can have a look on this

      https://community.oracle.com/thread/3689943?tstart=0

      Delete
  35. Sameh greeting and,
    I acted according to the instructions of your blog "Using Jasper Report In ADF Application (Step-by-Step)", but when you do everything right when I select any record from the table that opens and press the Run button repot, not otavra is no report nor shows no error. Please if you have any idea where it might be a mistake to me pomogmen.
    Greetings
    Drasko
    My email: drasko.kosovic@gmail.com

    ReplyDelete
    Replies
    1. Do you run the report from page fragment (.jsff)? if yes, you have to use servlet to run the report. you can check this url
      https://community.oracle.com/thread/3689943?tstart=0

      If you use normal page .jspx or .jsf be sure that the button partailSubmit set to "false"

      Delete
  36. Hy Sameh!
    Greetings
    I want to run report with more than one parameters, I've tried various things in my bean but couldn't do so, any suggestion please?

    ReplyDelete
    Replies
    1. It should be like:
      Map m = new HashMap();
      m.put("employeeId", empId);
      m.put("param2", value2);
      m.put("param3", value3);
      .
      .
      runReport("empReport.jasper", m);

      Delete
  37. Thank you Very Much Mr.Sameh,
    Very Clear and Easy to Understand...

    ReplyDelete
  38. Dear Sameh,

    Thank you very much for the valuable post!
    But I have a question regarding this post, in this post you are talking about integrated server what if I have reports on Standalone server?? how I can access those reports.

    Thanks,
    Best Wishes

    ReplyDelete
    Replies
    1. Jasper report is xml file will be included in the Ear file of your application, so if you create ear file and deploy it in standalone server it should work without any additional steps or configurations

      Delete
  39. Hello Mr Sameh,

    Hope you are doing fine.

    I have tried the example above with the following codes below.. however the report is not being displayed on the browser. the browser page simply refreshes on itself. Any idea what could be wrong please?

    HttpServletResponse response = getResponse();
    ServletOutputStream out = response.getOutputStream();
    response.setHeader("Cache-Control", "max-age=0");
    response.addHeader("Content-Disposition", "attachment; filename=report.pdf");

    response.setContentType("application/pdf");
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    InputStream is = loader.getResourceAsStream("ContainerHistoricReport.jasper");
    jasperPrint =JasperFillManager.fillReport(is, null,beanCollectionDataSource);

    JasperExportManager.exportReportToPdfStream(jasperPrint, out);
    FacesContext.getCurrentInstance().responseComplete();

    ReplyDelete
    Replies
    1. - Any error appear in the log?
      - Are you run in normal page or page fragment(.jsff)?
      - Is in 11g or 12c application?
      - Did you try to download my application and run it? is it running successfully?
      - Is button's (which you press on it to run the report) partialSubmit="false"?

      Delete
  40. Very good post. Thank you, you've helped me a lot. Keep up the good work

    ReplyDelete
  41. HI Samesh,
    Very help full blog. I above all the steps, "Run Report" button working fine, when i created Jasper Report from system working fine. when i used jasper report which are created by others with (Same version 4..0.1) then i am facing issue.

    C:\Users\Janbi Shaik\AppData\Roaming\JDeveloper\system12.2.1.3.42.170820.0914\DefaultDomain\test_report_1588845728107_344653.java:52: error: cannot find symbol
    private JRFillVariable variable_COLUMN_COUNT = null;
    ^
    symbol: class JRFillVariable
    location: class test_report_1588845728107_344653
    31 errors
    at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:191)
    at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:215)
    at oracle.tri.view.JasperReports.doGet(JasperReports.java:173)
    <ADFContext leak detected.
    help me in this

    I am using Jdeveloper 12.2.1.3.0 and on .jsff page i have Run Report button

    ReplyDelete
    Replies
    1. Can you create a dummy ADF application and use the same code and same report but run it in .jspx page instead of .jsff page. If it works fine, it means jasper report has an issue with the region and need more investigation

      Delete