views:

127

answers:

4

I'm generating a Crystal Reports report which will ultimately need to be split into thousands of pdf files. What would be ideal would be if Crystal Reports had something like a "file break", like a page break, that you could insert into the file at the appropriate places.

I will need reasonably fine control over the file names, as well....something like "fileName_{CustomerId}_{CustomerIsLocal}.pdf".

I'm presuming a third-party piece of software will probably be needed. Thoughts?

TIA.

+2  A: 

I do not think Crystal supports such functionality. We currently manage this ourselves in our application, asspecially where the name format is required to be customized, and your intensions are to run the report for a Customer Group. You will have to look at doing this job using some code (C# is what we used).

If you have more questions in this regard, Please feel free to ask, so that i can assist.

Adriaan

astander
+1  A: 

The functionality you're looking for is generally referred to as "bursting". While there are various third-party tools to do this, Business Objects Enterprise also can (though Crystal Reports Server can't). It might be out of your price range, but it's definitely worth looking at for the flexibility it gives you in report distribution...

SarekOfVulcan
+1  A: 

I wanted to document this for anyone else who shows up looking for the answer:

private readonly CrystalReportViewer reportViewer = new CrystalReportViewer();
...
this.reportViewer.ReportSource = @"C:\PathToReport\Report.rpt";

using (var crystalReport = new ReportDocument())
{
    foreach (DataRow row in dataSet.Tables[0].Rows)
    {
     var customerId = int.Parse(row["customerId"].ToString());
     var isCurrent = bool.Parse(row["isCurrent"].ToString());
     var totalSales = int.Parse(row["totalSales"].ToString());

     // generate the report for each row
     this.CreateReport(customerId, isCurrent, totalSales, crystalReport);
    }
}

private void CreateReport(int customerId, bool isCurrent, int totalSales, ReportDocument crystalReport)
{
    crystalReport.Load(this.reportViewer.ReportSource.ToString());

    crystalReport.SetParameterValue("customerId", customerId);
    crystalReport.SetParameterValue("isCurrent", isCurrent);
    crystalReport.SetParameterValue("TotalSales", totalSales);

    var fileName = string.Format("EndOfYear_{0}_{1}.pdf", customerId, isCurrent ? 1 : 0);

    var outputPath = Path.Combine(this.txtOutputDirectory.Text, fileName);

    crystalReport.ExportToDisk(ExportFormatType.PortableDocFormat, outputPath);
}

References:

CrystalDecisions.CrystalReports.Design CrystalDecisions.CrystalReports.Engine

This code yields a filename like so:

"EndOfYear_123456_1.pdf"

It is certainly possible to generate the report object for each row, rather than passing it in, but slows things down quite a bit. Reusing the same report object doesn't have any negative impact as far as I could see, and made things go about ten times faster.

The only other thing you need is how to prepare a Crystal report, which is beyond the scope of this tutorial. Good luck!

Chris B. Behrens
A: 

I found DocumentBurster as a good report bursting & distribution solution. The tool itself is light - yet can work with Crystal Reports and many other reporting engines. The software is available in both commercial and open source licenses.

Doru