How to Merge Multiple Reports into a Single PDF in .NET
Merging multiple reports together is one of the most commonly asked questions from our customers in many business environments.
For example, say your organization has multiple offices across the world and each office has its own report showcasing the sales for a particular year. You are asked to create a presentation that analyses the company’s sales, by region. You have multiple sales reports, you need to analyse and present all of the sales data in one report. In this use case, all of the reports will need to be merged together into a single PDF.
This article demonstrates how to merge multiple reports together into a PDF using .NET framework. PDF for .NET uses familiar .NET syntax to generate PDFs from your C# or VB.NET applications. These PDFs can be generated from UI elements, like grids and charts, HTML, or data sources. PDF for .NET supports commonly used PDF features like forms, security, compression, and more.
We will be using ComponentOne PDF in this demo. ComponentOne PDF actually allows you to create PDF documents from an application.
Merging Multiple Reports Together using the .NET framework
Step 1:
Create a list of C1FlexReport objects and add reports to it by creating an extension method for C1PdfDocument.
public static void AddC1FlexReport(this C1PdfDocument _pdfDoc, C1FlexReport c1FlexReport)
{
pdfDocument = _pdfDoc;
//Create C1PdfGraphics
_pdfGraphics = new C1PdfGraphics(_pdfDoc);
C1FlexReport _flex = new C1FlexReport();
//Copy report definition
_flex.ReportDefinition = c1FlexReport.ReportDefinition;
//Add report to list
c1FlexReports.Add(_flex);
}
Step 2:
Get each page from every report object after rendering. Now, draw this retrieved C1Page on a specified C1PdfGraphics.
The extension method (RenderPdf) accomplishes this step.
public static void RenderPdf(this C1PdfDocument _pdfDoc, bool IsPageSequential = false)
{
//Render report(s) and calculate total page count for all report(s)
foreach (var c1FlexReport in c1FlexReports)
{
c1FlexReport.Render();
totalPages += c1FlexReport.PageCount;
}
//For sequential page number
if (IsPageSequential)
{
foreach (var c1FlexReport in c1FlexReports)
{
c1FlexReport.StartPage += C1FlexReport_StartPage;
c1FlexReport.Render();
}
}
foreach (var c1FlexReport in c1FlexReports)
{
C1Document _doc = c1FlexReport.Document;
for (int i = 0; i < c1FlexReport.PageCount; i++)
{
if (_pdfDoc.Pages.Count > 1 || i > 0)
{
//New page added in C1PdfDocument
_pdfDoc.NewPage();
}
//Get C1Page from C1FlexReprot using index
C1Page page = c1FlexReport.GetPage(i);
_pdfDoc.PageSize = new SizeF((float)(Unit.Convert(page.FullWidth, _doc.MeasurementUnits, UnitTypeEnum.Point)), (float)(Unit.Convert(page.FullHeight, _doc.MeasurementUnits, UnitTypeEnum.Point)));
// calculate scale factor
double sx = _pdfDoc.PageSize.Width / Unit.Convert(page.FullWidth, _doc.MeasurementUnits, UnitTypeEnum.Dip);
double sy = _pdfDoc.PageSize.Height / Unit.Convert(page.FullHeight, _doc.MeasurementUnits, UnitTypeEnum.Dip);
// translate/scale
_pdfDoc.Write("{0} 0 0 {1} {2} {3} cm\r\n",
DoubleToString(sx), DoubleToString(sy),
DoubleToString(0), DoubleToString(-0 + _pdfDoc.PageRectangle.Height * (1 - sy)));
// draw page using pdf graphics
page.Draw(_pdfGraphics, new Point(0, 0), null, null, DrawAttrs.Default);
}
AddOutlines(_doc.Outlines);
}
}
//Convert Double to String
private static string DoubleToString(double _double)
{
return _double.ToString("0.###", CultureInfo.InvariantCulture);
}
private static void AddOutlines(OutlineNodeCollection onc)
{
foreach (var outlineNode in onc)
{
if (outlineNode.LinkTarget is C1LinkTarget)
{
var target = ((C1LinkTarget)outlineNode.LinkTarget).Bookmark;
pdfDocument.AddBookmark(outlineNode.Caption, outlineNode.Level, target);
if (outlineNode.HasChildren)
AddOutlines(outlineNode.Children);
}
}
}
private static void C1FlexReport_StartPage(object sender, ReportEventArgs e)
{
//Update the text of page footer for printing the page number and page count in sequence
((sender as C1FlexReport).Fields["ftrRight"] as TextField).Text = "Page " + page + " of " + totalPages;
page++;
}
Step 3:
Add C1FlexReport objects to a C1PdfDocument and save the file using C1PdfDocument’s save method.
_pdfDoc.AddC1FlexReport(c1FlexReport1);
_pdfDoc.AddC1FlexReport(c1FlexReport2);
_pdfDoc.RenderPdf(true);
_pdfDoc.Save("MergeReport.pdf");
Step 4:
The resultant PDF file can also be displayed in C1FlexViewer using C1PdfDocumentSource.
C1PdfDocumentSource c1PdfDocumentSource = new C1PdfDocumentSource();
c1PdfDocumentSource.LoadFromFile("MergeReport.pdf");
c1FlexViewer3.DocumentSource = c1PdfDocumentSource;
After this step, you will have a merged PDF file containing all the reports together.
Learn more about PDF for Winforms
Download C# sample
Download VB sample
If you have any questions about this tutorial, please leave us a comment. Additionally, if you have a request for a specific demo, be sure to leave a comment below!