Search code examples
javajspcrystal-reportsbusiness-objectscrystal-reports-xi

Programmatically append Crystal Reports without using subreports


My task is to create an "app" that will allow the following: given a list of Crystal Reports on the server, the user can select any number of them to combine into one long report (just appended together). They must be able to set the parameters for each report.

I've gathered that the usual method would be to generate a main report that includes all of the individual reports as subreports, but I don't believe this is an option here, because some of the individual reports may already contain their own subreports (and you can't have nested subreports).

The reports were created with Crystal Reports for Enterprise XI 4.0. I'm trying to do this as a set of JSP pages using the BusinessObjects Java SDK. Preferably the output type would be flexible, but if necessary, just generating a PDF would be acceptable.

What would be the best way to go about this?

UPDATE: I should also note that, when attempting to export a single report to PDF (I was considering just making PDFs of every report and then concatenating them somehow), the following code fails:

// Get the ID of the current working report.
int reportID = Integer.parseInt(request.getParameter("ReportID"));

// Retrieve the BOE Session and InfoStore objects
IEnterpriseSession eSession = (IEnterpriseSession)session.getAttribute("EnterpriseSession");
IInfoStore iStore = (IInfoStore)eSession.getService("InfoStore",ServiceNames.OCA_I_IINFO_STORE);

// Query to get the report document
String infoStoreQuery = "select SI_NAME,SI_PARENTID from CI_INFOOBJECTS where SI_ID=" + reportID;
IInfoObjects infoObjects = iStore.query(infoStoreQuery);
IInfoObject report = (IInfoObject)infoObjects.get(0);

IReportAppFactory reportAppFactory = (IReportAppFactory)eSession.getService("RASReportFactory");
ReportClientDocument clientDoc = reportAppFactory.openDocument(report, OpenReportOptions._openAsReadOnly, java.util.Locale.CANADA);

//Use the report document's PrintOutputController to export the report to a ByteArrayInputStream
ByteArrayInputStream byteIS = (ByteArrayInputStream)clientDoc.getPrintOutputController().export(ReportExportFormat.PDF);
clientDoc.close();

//Create a byte[] that is the same size as the exported ByteArrayInputStream
byte[] buf = new byte[2000 * 1024];
int nRead = 0;
//Set response headers
response.reset();
response.setHeader("content-disposition", "inline;filename=untitled.pdf");
response.setContentType("application/pdf");
//Send the Byte Array to the Client
while ((nRead = byteIS.read(buf)) != -1) {
  response.getOutputStream().write(buf, 0, nRead);
}
//Flush the output stream
response.getOutputStream().flush();
//Close the output stream
response.getOutputStream().close();

On the "reportAppFactory.openDocument" line, with this error:

javax.servlet.ServletException: com.crystaldecisions.sdk.occa.managedreports.ras.internal.ManagedRASException: Cannot open report document. --- This release does not support opening SAP Crystal Reports for Enterprise reports.

So if you don't have a better solution to the overall problem, I would still appreciate some help on even exporting one report to PDF.


Solution

  • I'll limit my answer to what seems to be the hardest part of your question - combining the output into one file.

    What you're describing doesn't sound possible through Crystal Reports unless you create a 'master' report and append each report as a subreport. This would indeed have the drawback you mention of losing any already embedded subreports.

    The reason it would be required to do it like this is due to the following properties of a Crystal Report:

    1. a report can have a single datasource; different datasources must be encapsulated inside subreports
    2. a report is made up of report-header, page-header, group-headers, details, group-footers, report-footer, page-footer - always in that order.

    A report that consisted of appending multiple reports together would most likely break #1 (if they have different datasources), and would definitely break #2.

    Now, you're not without options - you can export reports to various formats, and programmatically append them in that exported format: MS Excel/Word, PDF, and manipulate them in that format. There are a few free pdf writers that let you print out a single document to PDF (so you don't even need to rely on CR's export feature); there are some tools that can merge multiple pdfs together try the options from this google search, or this SO answer.

    Edit - on the error you're getting (This release does not support opening SAP Crystal Reports for Enterprise reports.) - it sounds like you're trying to open a newer versioned report in an older SDK. Make sure the SDK you're using supports the version of reports you're trying to use it with (perhaps it was installed incorrectly, or there are multiple versions conflicting?)