Problem Definition
I have a performance problem displaying large/huge resultset of data on a crystal report. The report takes about 4 minutes or more depending on the resultset size.
How do you handle large resultsets in Crystal Reports without a performance issue?
Environment
Crystal Reports XI
Apache WebSvr 2.X
Jboss 4.2.3
Struts
Java Reporting Component (JRC)
Crystal Report Viewer (CRV)
Firefox
Details
I use the CRXI thick client to build my report (.rpt) and then use it in my webapplication (webapp) under Jboss.
User specifies the filter criteria to generate a report (date range etc) and submits the request to the webapp. Webapp queries the database, gets a "resultset".
I initialize the JRC and CRV according to all the specifications and finally call the "processHttpRequest" method of Crystal Report Viewer to display the report on browser.
So.....
Request received to generate a report with a filter criteria
Query DB to get resultset
Initialize JRC and CRV
finally display the report by calling
reportViewer.processHttpRequest(request, response, request.getSession().getServletContext(), null);
The performance problem is within the last step. I put logs everywhere and noticed that database query doesnt take too long to return resultset. Everything processes pretty quickly till I call the processHttpRequest of CRV. This method just hangs for a long time before displaying the report on browser.
CRV runs pretty fast when the resultset is smaller, but for large resultset it takes a long long time.
I do have subreports and use Crystal report formulas on the reports. Some of them are used for grouping also. But I dont think Subreports is the real culprit here. Because I have some other reports that dont have any subreports, and they too get really slow displaying large resultsets.
Solutions?
So obviously I need a good solution to this generic problem of "How do you handle large resultsets in Crystal Reports?"
I have thought of some half baked ideas.
A) Use external pagination and fetch data only for the current page being displayed. But for this, CRXI must allow me to create my own buttons (previous, next, last), so I can control the click event and fetch data accordingly. I tried capturing events by registering event handler "addToolbarCommandEventListener" of CRV. But my listener gets invoked "after" processHttpRequest method completes, which doesnt help.
Some how I need to be able to control the UI by adding my own previous page, next page, last page buttons and controlling it's click events.
B) Have CRXI use a jquery type of functionality, to allow browser side page navigation. So maybe the first time it'll take 5 mins to display the report, but once it's displayed, user can go to any page without sending the request back to server.
C) Try using Crystal Reports 2008. I'm open to using this version, but I couldnt figureout if it has any features that can help me.
D) Use BIRT or JasperReports, since they apparently have the ability to handle large datasets, by caching a part of the dataset on disk etc...
E) Will using the Crystal Reports Servers like cache server, application server etc help in any way? I read a little on the Crystal Page Viewer, Interactive Viewer, Part Viewer etc....but I'm not sure if any of these things are going to solve the issue.
I'd appreciate it if someone can point me in the right direction.
Related
I'm working on Jasper Reports using JasperSoft Studio. I have a huge data set (around 50 million) that needed to be filled in the reports. I can able to get them with pagination.
But unfortunately while I try to export data in Excel/PDF formats where pagination cannot be applied as per the requirement, it is taking too long to load ANY data and the user has to wait until the report generation is over.
Is there any way to generate and send the data to the client and keep them adding there after? So that the user will know something is loading instead of make them to wait for long time.
I tried the settings given here, http://community.jaspersoft.com/questions/534989/settings-required-generating-large-reports. But still It is loading the file altogether only and not in an expected way.
Any help on this would be greatly appreciated.
I have really low knowledge on Java and JasperReports, barely used those to play around, nothing too serious. A friend of mine has been trying to get someone to develop him an application that will generate PDFs with information from an access database for each of his clients, however, after 6 months and 7 developers who ditched him, he has found none, so he asked me if I could help him to which I said I'd give it a try.
What I have been able to do so far:
So far I've managed to successfully (Everything has been done separately, I have like 8 projects in total so far):
Use Jaspersoft Studio/iReport to create a single PDF with the required client information on each sheet.
Create a separate JasperReports project with a input field to get a pdf with a single client information.
Create a Java App with a JFrame to launch the report generation.
Create a Java App to connect to the access database through ucanaccess and validate the search criteria
Questions:
Now, after a few days on Google up and down I havnt managed to successfully achieve everything that I'd like to achieve, and I'd love if someone could either point me into good noob-proof guides or (if willing) provide a noob-proof answer so I can continue to move on.
Create a Java App where you can choose to generate all client's report or a single report for a specified client (I am assuming this isn't too complicated since it'd just be a matter to embed both Jasper reports into the java app), however I'd need to pass the input value into jasper report field to generate a single report (Not sure if this one was clear enough), and run the query for the data-set based on that field's value.
Ideally though not highly needed, pass yet another variable as a field to set a date range.
Since this is being done on a MS Access Database -*.accdb- (Don't blame me, I've been telling him to move to MySQL/SQL for quite a while now), I'd love to know if its possible to make JasperReports do a query based on a UCanAccess JDBC connection (Tried a few options, none worked).
Finally, I need to generate in the report a date range (Something like: "Between 1/Jan/2014 and 1/Feb/2014")
I feel like I've made a decent amount of progress so far, but since I am no pro on either JasperReports nor Java, I am getting stuck in a point where more knowledge is required to create a more decent and practical piece of software and I'd love if someone could point me into a better direction (Either if something is impossible or just a few links to help me get thru)
-Remeber to add ucanaccess jar and all dependencies jars in the Driver Classpath, while creating the Data Adapter
-You have to set Showschema=true:
e.g.
jdbc:ucanaccess://c:/db/database.accdb;Showschema=true
In this way Jasper Studio will be able to navigate the metadata of your database, and you'll find your tables under the PUBLIC schema.
Then you'll be able to create your reports as usual.
I wrote sql but it takes more time when execute it in jsp. And I want to make faster it. Will grid view make the page faster?
I'm junior in Java. I researched in google but didn't find clear sample about gridview. Can u help me?
I understand you have a web based application backed by the DB.
Note that gridview is not something offered by Java, instead you can create tables by using your web frameworks and render data there.
You say, it takes a lot of time to execute an SQL when running withing JSP. Where the time goes?
Running the SQL itself? Maybe creating a JSP or transmitting it to the client browser in an Html form, or even maybe the rendering of your table in browser?
You should detect the bottleneck in order to understand what you're going to fix
Consider to use profiler and see (at least on server vm) where the time goes.
I think JVisualVM will suit your needs here.
Hope this helps
I would have done this task using following steps
Create one servlet.
Connect to the database and fetch the data which we have to display.
Create a list and keep the data in list it.
Set the list in request and forward the control to JSP.
On JSP, use DisplayTag to show the data in grid form.
Hope this helps you.
I have a reporting system where I need to combine data from 3 diffrent servers(systems) show it to users . This works fine as far as there few thousand records but as it increases system times out .
I was thinking to use another approach . When user runs result I will generate a request to generate report to database. A daemon running will pick it up and gather data and generate a report and will email to user a link to reporting data . I can do multiple things here .
1)insert gathered data to database in form where it can be simply displayed to users on page.
2)generate html and store it to database .
Although I think 1st option is best here are there any other suggestions ?
Several thoughts:
Consider using hadoop to make your report processing very scalable
Consider running the reports on an interval (e.g. every hour). When the user requests a report you can immediately show them the most recently generated report.
Definitely do not store html. Instead render it when the user makes the request. By the way, this also gives you the flexibility to show different versions of the reports to different users
I'm currently working on a Struts 2 application with Spring as backend with MySQL database.
Right now fetching 1000+ rows on page load.
I'm using tablesorter jquery plugin for displaying the results,sorting on click and pagination purpose.
But the page is taking lot of time to load and also it hangs in IE !!
Is there any easier way to do this like fetching required data from database as and when the user makes the selection like fetch first 10 rows,sorting data,etc.
Any ideas to make the application work faster are welcome !!
I couldn't tell from the docs if the plugin supported server-side paging or not, but that'd be one thing to consider. It was unclear if its paging plugin had any options for this.
Does the plugin's example with a thousand students crash under the same circumstance?