Agile FAQs
  About   Slides   Home  

 
Managed Chaos
Naresh Jain's Random Thoughts on Software Development and Adventure Sports
     
`
 
RSS Feed
Recent Thoughts
Tags
Recent Comments

Crystal Reports PLUS Struts

<b>Steps to integrate crystal reports with Strut’s app</b>

1. Provide a link from your web-app, which will trigger the report. Usually we have a form, which will do this.
html:form action=”/generateReport” target=”_blank”

2. Update the struts-congif.xml file to redirect “/generateReport” to the appropriate action class

3. Write the following GenerateReportAction class to handle the report generation logic.

That’s it. You will see the report.

package com.xyz.abc.web.servlet;

import com.crystaldecisions.report.web.viewer.CrystalReportViewer;
import com.crystaldecisions.reports.reportengineinterface.JPEReportSourceFactory;
import com.crystaldecisions.sdk.occa.report.data.Fields;
import com.crystaldecisions.sdk.occa.report.data.ParameterField;
import com.crystaldecisions.sdk.occa.report.lib.ReportSDKExceptionBase;
import com.crystaldecisions.sdk.occa.report.reportsource.IReportSource;
import com.crystaldecisions.sdk.occa.report.reportsource.IReportSourceFactory2;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

public class GenerateReportAction extends Action {
public ActionForward actionExecuted(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, ActionErrors errors) throws IOException, ServletException {
String reportName = System.getProperty(REPORT_NAME, “Report1.rpt”);
final ActionForm reportForm = (ReportForm) form;
List paramList = getReportParams(reportForm);
CrystalReportViewer reportViewer = createReportViewer(reportName, paramList, request.getLocale());
try {
reportViewer.processHttpRequest(request, response, getServlet().getServletContext(), response.getWriter());
} catch (ReportSDKExceptionBase reportSDKExceptionBase) {
reportSDKExceptionBase.printStackTrace();
} finally {
reportViewer.dispose();
}
return (mapping.findForward(“success”));
}

private CrystalReportViewer createReportViewer(String reportName, List params, Locale locale) {
CrystalReportViewer reportViewer = new CrystalReportViewer();
try {
IReportSourceFactory2 rptSrcFactory = new JPEReportSourceFactory();
IReportSource reportSource = (IReportSource) rptSrcFactory.createReportSource(reportName, locale);
reportViewer.setReportSource(reportSource);
Fields fields = createParamterFields(params);
reportViewer.setParameterFields(fields);
setReportViewerProperties(reportViewer);

return reportViewer;
} catch (ReportSDKExceptionBase e) {
throw new IllegalStateException(e.getMessage());
}
}

private Fields createParamterFields(List params) {
Fields fields = new Fields();
for (Iterator iterator = params.iterator(); iterator.hasNext();) {
ReportParams reportParam = (ReportParams) iterator.next();
ParameterField parameterField = newParameterField(reportParam.getParamName(), reportParam.getParamValue());
fields.add(parameterField);
}
return fields;
}

private void setReportViewerProperties(CrystalReportViewer reportViewer) {
reportViewer.setHasRefreshButton(false);
reportViewer.setHasExportButton(true);
reportViewer.setEnableParameterPrompt(true);
reportViewer.setEnableLogonPrompt(true);
reportViewer.setHasLogo(false);
}

private ArrayList getReportParams(ActionForm ReportForm) {
ArrayList outParamList = new ArrayList();
outParamList.add(new ReportParams(“param1”, ReportForm.getParamOne()));

return outParamList;
}

public static ParameterField newParameterField(String name, String dataValue) {
ParameterField field = new ParameterField();
field.setName(name);
field.setReportName(“”);
field.getCurrentValues().add(dataValue);
return field;
}
}

Things to watch out:

1. html:form action=”/generateReport” target=”_blank”
Since crystal report has it’s own menu, it’s better to open the report in a separate blank page. If we don’t do so, when we click on any of the menu items, actually a form submission takes place and struts will interfere with it.

2. While creating parameter fields, make sure you do the following field.setReportName(“”);
Though, it does not make any sense to set the reportName to blank string, it is a must, else the parameters will not be passed to the report. If inside the report you try to access these parameters, then Crystal Reports will throw the following exception and redirect you to a page, which asks for the missing parameters.
05 Feb 2005 16:17:01 [http80-Processor25] ERROR com.crystaldecisions.reports.formatter.formatter.objectformatter – com.crystaldecisions.reports.dataengine.al: Some parameters are missing values
05 Feb 2005 16:17:01 [http80-Processor25] ERROR com.crystaldecisions.reports.reportengineinterface – Error formatting page
com.crystaldecisions.reports.formatter.formatter.c: Some parameters are missing values
at com.crystaldecisions.reports.formatter.formatter.objectformatter.bf.<init>(Unknown Source)
at com.crystaldecisions.reports.formatter.formatter.objectformatter.bf.a(Unknown Source)
at com.crystaldecisions.reports.formatter.formatter.d.j.<init>(Unknown Source)
at com.crystaldecisions.reports.formatter.formatter.d.j.if(Unknown Source)
at com.crystaldecisions.reports.reportengineinterface.Engine.getPage(Unknown Source)
at com.crystaldecisions.reports.reportengineinterface.JPEReportSource.getPage(Unknown Source)
at com.crystaldecisions.report.web.viewer.ReportAgent.a(Unknown Source)
at com.crystaldecisions.report.web.viewer.CrystalReportViewer.goto(Unknown Source)
at com.crystaldecisions.report.web.ServerControl.a(Unknown Source)
at com.crystaldecisions.report.web.ServerControl.getHtmlContent(Unknown Source)
at com.thoughtworks.clearinghouse.web.servlet.GenerateSummaryReportAction.actionExecuted(GenerateSummaryReportAction.java:51)
at com.thoughtworks.clearinghouse.web.servlet.AbstractAction.execute(AbstractAction.java:40)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:437)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:264)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1109)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:470)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:284)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:245)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:199)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:195)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:164)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:156)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:211)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:805)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:696)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
at java.lang.Thread.run(Thread.java:534)
Caused by: com.crystaldecisions.reports.dataengine.al: Some parameters are missing values
at com.crystaldecisions.reports.dataengine.a0.a(Unknown Source)
… 42 more
Even after setting reportName to blank string, we still get this error, but the values are passed correctly to the report.

Does someone have a solution, how to get rid of this exception?


    Licensed under
Creative Commons License