Tuesday, March 27, 2012
Combining reports into a single PDF
financial reports using RS. The goal has always been to package them
into a single PDF, with different users receiving customized versions
of each report (eg, everyone in NY gets #s for the NY office).
We've just learned that if we combine the reports as subreports, we
lose the page headers and footers, and landscape and portrait reports
cannot be combined.
But we still have to deliver the package somehow. Does anyone have an
recommendations? We're looking at:
-Putting the page footers and headers in the report body some way.
-Writing an app to automate Adobe distiller and build the packages
ourselves (but we lose the RS delivery functionality)
-Leaving the reports as separate PDFs, and writing an app that will
print them all, creating the appearance of a single package at least
when printed.
Thanks,
BurtBurt
I had a similar problem but I could not resolve it via RS. Here is how I
solved it.
In my c# app I use the Render method for each report and save off its byte
array that is returns into a member variable pdfStream. When the report
generation was complete I then created a pdf with the byte array. Somethign
like this:
// Render Method
private byte[] m_bytResult;
m_bytResult = oRpts.Render(m_sName, GetReportFormat(false), showHideToggle,
m_sDevice, m_oParms, credentials, showHideToggle, out encoding, out mimeType,
out reportHistoryParameters, out warnings, out streamIDs);
// Generate Single PDF From Results of RS Render
string sOut = "myNewReports.pdf";
FileStream stream = File.Create( sOut, bytResult.Length );
stream.Write( bytResult, 0, bytResult.Length );
stream.close;
I hope this helps some.
Tom
"Burt" wrote:
> My company has spent the last few months developing a set of complex
> financial reports using RS. The goal has always been to package them
> into a single PDF, with different users receiving customized versions
> of each report (eg, everyone in NY gets #s for the NY office).
> We've just learned that if we combine the reports as subreports, we
> lose the page headers and footers, and landscape and portrait reports
> cannot be combined.
> But we still have to deliver the package somehow. Does anyone have an
> recommendations? We're looking at:
> -Putting the page footers and headers in the report body some way.
> -Writing an app to automate Adobe distiller and build the packages
> ourselves (but we lose the RS delivery functionality)
> -Leaving the reports as separate PDFs, and writing an app that will
> print them all, creating the appearance of a single package at least
> when printed.
> Thanks,
> Burt
>|||Thanks, Tom.
Looks like I'm going to have to resort to this- write all combinations
of the customized reports to a file structure, combine them per below,
then write a process to email them. Ug.
Burt
Tom Walls <TomWalls@.discussions.microsoft.com> wrote in message news:<E674D836-A609-4FC2-8B4C-46222FC11C1D@.microsoft.com>...
> Burt
> I had a similar problem but I could not resolve it via RS. Here is how I
> solved it.
> In my c# app I use the Render method for each report and save off its byte
> array that is returns into a member variable pdfStream. When the report
> generation was complete I then created a pdf with the byte array. Somethign
> like this:
> // Render Method
> private byte[] m_bytResult;
> m_bytResult = oRpts.Render(m_sName, GetReportFormat(false), showHideToggle,
> m_sDevice, m_oParms, credentials, showHideToggle, out encoding, out mimeType,
> out reportHistoryParameters, out warnings, out streamIDs);
> // Generate Single PDF From Results of RS Render
> string sOut = "myNewReports.pdf";
> FileStream stream = File.Create( sOut, bytResult.Length );
> stream.Write( bytResult, 0, bytResult.Length );
> stream.close;
>
> I hope this helps some.
> Tom
> "Burt" wrote:
> > My company has spent the last few months developing a set of complex
> > financial reports using RS. The goal has always been to package them
> > into a single PDF, with different users receiving customized versions
> > of each report (eg, everyone in NY gets #s for the NY office).
> >
> > We've just learned that if we combine the reports as subreports, we
> > lose the page headers and footers, and landscape and portrait reports
> > cannot be combined.
> >
> > But we still have to deliver the package somehow. Does anyone have an
> > recommendations? We're looking at:
> >
> > -Putting the page footers and headers in the report body some way.
> > -Writing an app to automate Adobe distiller and build the packages
> > ourselves (but we lose the RS delivery functionality)
> > -Leaving the reports as separate PDFs, and writing an app that will
> > print them all, creating the appearance of a single package at least
> > when printed.
> >
> > Thanks,
> >
> > Burt
> >|||Did anyone come up with a better way to do this? Seems like something a lot
of people would want to do, if you actually want to be able to log in to
Reports Manager and get a nice clean report every so often (with cover page,
TOC, et al). Otherwise it means RS is really only good for us IT guys. Anyone
from MSFT know if this kind of feature is on the horizon?
"Burt" wrote:
> Thanks, Tom.
> Looks like I'm going to have to resort to this- write all combinations
> of the customized reports to a file structure, combine them per below,
> then write a process to email them. Ug.
> Burt
>
> Tom Walls <TomWalls@.discussions.microsoft.com> wrote in message news:<E674D836-A609-4FC2-8B4C-46222FC11C1D@.microsoft.com>...
> > Burt
> >
> > I had a similar problem but I could not resolve it via RS. Here is how I
> > solved it.
> >
> > In my c# app I use the Render method for each report and save off its byte
> > array that is returns into a member variable pdfStream. When the report
> > generation was complete I then created a pdf with the byte array. Somethign
> > like this:
> >
> > // Render Method
> > private byte[] m_bytResult;
> >
> > m_bytResult = oRpts.Render(m_sName, GetReportFormat(false), showHideToggle,
> > m_sDevice, m_oParms, credentials, showHideToggle, out encoding, out mimeType,
> > out reportHistoryParameters, out warnings, out streamIDs);
> >
> > // Generate Single PDF From Results of RS Render
> > string sOut = "myNewReports.pdf";
> > FileStream stream = File.Create( sOut, bytResult.Length );
> > stream.Write( bytResult, 0, bytResult.Length );
> > stream.close;
> >
> >
> > I hope this helps some.
> >
> > Tom
> >
> > "Burt" wrote:
> >
> > > My company has spent the last few months developing a set of complex
> > > financial reports using RS. The goal has always been to package them
> > > into a single PDF, with different users receiving customized versions
> > > of each report (eg, everyone in NY gets #s for the NY office).
> > >
> > > We've just learned that if we combine the reports as subreports, we
> > > lose the page headers and footers, and landscape and portrait reports
> > > cannot be combined.
> > >
> > > But we still have to deliver the package somehow. Does anyone have an
> > > recommendations? We're looking at:
> > >
> > > -Putting the page footers and headers in the report body some way.
> > > -Writing an app to automate Adobe distiller and build the packages
> > > ourselves (but we lose the RS delivery functionality)
> > > -Leaving the reports as separate PDFs, and writing an app that will
> > > print them all, creating the appearance of a single package at least
> > > when printed.
> > >
> > > Thanks,
> > >
> > > Burt
> > >
>
Combining multiple subreports into a single report
Thanks!
I did check the landscape width for the reports both individualy and in the master report. They all render fine independently. I also tested the report rendering as I added each subreport to the master report. The moment I added the Landscape one, all portrait reports (that rendered fine before) spilled over onto subsequent pages. The subreports are embedded in a main report and not linked. Can you tell me more about how you configured your reports to be linked?
Thanks!
|||I appologize I meant reducing the body width to portrait regardless of the fact that you have reports set to landscape. I believe at runtime the report server will expand the body width as needed.
A linked report is essentially a smart pointer to the actual report. You can create a linked reportin in the Report Manager. Go to the report properties and click on the Create Linked Report button. The advantage of having this point of indirection is that if the standalone report is moved, the linked report will automatically be redirected to the new location. Also, a linked report can have its own security policies, etc.
|||Hi,
I was able to find information at this link:
http://msdn2.microsoft.com/en-us/library/ms155993.aspx
"Reporting Services does not provide a way to combine landscape and portrait mode pages in the same report, nor does it provide a way to create a print-based layout that replaces or exists alongside the layout of a report as rendered in a browser or other application. For most exported reports, report printouts include everything that is visible on the report, as viewed by the user on a computer monitor."
Not what I wanted to hear. Also, I was unable to find the Linked Reports option within Report Designer Report Properties. We are using Visual Studio 2005. Someone on the team provided these links for combining PDFs. This seems like a lot of work to go thru because of a missing feature. Even Word allows you to insert section breaks where you can specigy Landscapre or Portrait.
http://www.codeproject.com/cs/library/giospdfnetlibrary.asp
https://secure.codeproject.com/csharp/giospdfsplittermerger.asp
|||Yes, this is correct. I appologize for giving you wrong information. Upon looking at our report package implementation, the master report width is set to Landscape. The Create Linked Report button is on the report properties (General Tab) assuming you use the Report Manager and have rights to create linked reports.
|||Hi,
The mechanism that we've used to achieve this is to write some code using a PDF library to combine the reports. It goes off and renders the reports and then adds them to a master document. That way we can add page numbers, table of contents etc. and its all dynamic.
Sanjay
|||Hi, and thanks.
That is what we ended up doing and I am posting the code for the benefit of others. We used PDFSharp (there are several others) and I modified one of their samples into the class below. It worked good and we ended up with one report that could have both landscape and portrait pages and page numbers.
#region PDFsharp - A .NET library for processing PDF
//
// Copyright (c) 2005-2006 empira Software GmbH, Cologne (Germany)
//
// http://www.pdfsharp.com
//
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.IO;
using PdfSharp;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
using PdfSharp.Drawing;
namespace successionManagement
{
public class CombinePdfs
{
public static PdfDocument combine(Stream[] streams, String fileName)
{
PdfDocument outputDocument = new PdfDocument();
XFont font = new XFont("arial", 8, XFontStyle.Regular);
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Center;
format.LineAlignment = XLineAlignment.Far;
XGraphics gfx;
XRect box;
int totalPages = 0;
int currentPage = 0;
PdfDocument[] pdfDocuments = new PdfDocument[streams.Length];
for (int i = 0; i < streams.Length; i++)
{
Stream stream = (Stream) streams;
PdfDocument inputDocument = PdfReader.Open(stream, PdfDocumentOpenMode.Import);
totalPages = totalPages + inputDocument.PageCount;
pdfDocuments = inputDocument;
}
String pageNbrFooter;
for (int i=0; i < pdfDocuments.Length; i++)
{
PdfDocument inputDocument = (PdfDocument) pdfDocuments;
for (int idx = 0; idx < inputDocument.PageCount; idx++)
{
PdfPage page = inputDocument.Pages[idx];
currentPage = currentPage + 1;
pageNbrFooter = "Page " + currentPage + " of " + totalPages;
page = outputDocument.AddPage(page);
//Write document file name and page number on each page
gfx = XGraphics.FromPdfPage(page);
box = page.MediaBox.ToXRect();
box.Inflate(20, -10);
gfx.DrawString(String.Format( pageNbrFooter,0 ),
font, XBrushes.Black, box, format);
}
}
outputDocument.Save(fileName);
return outputDocument;
}
}
}
To invoke the class you would supply your stream in place of the pdf and the relative path. Here is a simple hard-coded path example.
Stream[] streams = new Stream[5];
streams[0] = new FileStream(@."c:/Lynette/portrait1.pdf", FileMode.Open);
streams[1] = new FileStream(@."c:/Lynette/portrait2.pdf", FileMode.Open);
streams[2] = new FileStream(@."c:/Lynette/portrait3.pdf", FileMode.Open);
streams[3] = new FileStream(@."c:/Lynette/landscape1.pdf", FileMode.Open);
streams[4] = new FileStream(@."c:/Lynette/portrait4.pdf", FileMode.Open);
PdfDocument combinedPdf = CombinePdfs.combine(streams,"c:/Lynette/myCombined.pdf");
|||
The code sample above should have a subscript in brackets but I guess that is also the symbol for an idea. How funny!
Great solution to this issue. Thank you for posting the code!
Combining multiple subreports into a single report
Thanks!
I did check the landscape width for the reports both individualy and in the master report. They all render fine independently. I also tested the report rendering as I added each subreport to the master report. The moment I added the Landscape one, all portrait reports (that rendered fine before) spilled over onto subsequent pages. The subreports are embedded in a main report and not linked. Can you tell me more about how you configured your reports to be linked?
Thanks!
|||I appologize I meant reducing the body width to portrait regardless of the fact that you have reports set to landscape. I believe at runtime the report server will expand the body width as needed.
A linked report is essentially a smart pointer to the actual report. You can create a linked reportin in the Report Manager. Go to the report properties and click on the Create Linked Report button. The advantage of having this point of indirection is that if the standalone report is moved, the linked report will automatically be redirected to the new location. Also, a linked report can have its own security policies, etc.
|||Hi,
I was able to find information at this link:
http://msdn2.microsoft.com/en-us/library/ms155993.aspx
"Reporting Services does not provide a way to combine landscape and portrait mode pages in the same report, nor does it provide a way to create a print-based layout that replaces or exists alongside the layout of a report as rendered in a browser or other application. For most exported reports, report printouts include everything that is visible on the report, as viewed by the user on a computer monitor."
Not what I wanted to hear. Also, I was unable to find the Linked Reports option within Report Designer Report Properties. We are using Visual Studio 2005. Someone on the team provided these links for combining PDFs. This seems like a lot of work to go thru because of a missing feature. Even Word allows you to insert section breaks where you can specigy Landscapre or Portrait.
http://www.codeproject.com/cs/library/giospdfnetlibrary.asp
https://secure.codeproject.com/csharp/giospdfsplittermerger.asp
|||Yes, this is correct. I appologize for giving you wrong information. Upon looking at our report package implementation, the master report width is set to Landscape. The Create Linked Report button is on the report properties (General Tab) assuming you use the Report Manager and have rights to create linked reports.
|||Hi,
The mechanism that we've used to achieve this is to write some code using a PDF library to combine the reports. It goes off and renders the reports and then adds them to a master document. That way we can add page numbers, table of contents etc. and its all dynamic.
Sanjay
|||Hi, and thanks.
That is what we ended up doing and I am posting the code for the benefit of others. We used PDFSharp (there are several others) and I modified one of their samples into the class below. It worked good and we ended up with one report that could have both landscape and portrait pages and page numbers.
#region PDFsharp - A .NET library for processing PDF
//
// Copyright (c) 2005-2006 empira Software GmbH, Cologne (Germany)
//
// http://www.pdfsharp.com
//
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.IO;
using PdfSharp;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
using PdfSharp.Drawing;
namespace successionManagement
{
public class CombinePdfs
{
public static PdfDocument combine(Stream[] streams, String fileName)
{
PdfDocument outputDocument = new PdfDocument();
XFont font = new XFont("arial", 8, XFontStyle.Regular);
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Center;
format.LineAlignment = XLineAlignment.Far;
XGraphics gfx;
XRect box;
int totalPages = 0;
int currentPage = 0;
PdfDocument[] pdfDocuments = new PdfDocument[streams.Length];
for (int i = 0; i < streams.Length; i++)
{
Stream stream = (Stream) streams;
PdfDocument inputDocument = PdfReader.Open(stream, PdfDocumentOpenMode.Import);
totalPages = totalPages + inputDocument.PageCount;
pdfDocuments = inputDocument;
}
String pageNbrFooter;
for (int i=0; i < pdfDocuments.Length; i++)
{
PdfDocument inputDocument = (PdfDocument) pdfDocuments;
for (int idx = 0; idx < inputDocument.PageCount; idx++)
{
PdfPage page = inputDocument.Pages[idx];
currentPage = currentPage + 1;
pageNbrFooter = "Page " + currentPage + " of " + totalPages;
page = outputDocument.AddPage(page);
//Write document file name and page number on each page
gfx = XGraphics.FromPdfPage(page);
box = page.MediaBox.ToXRect();
box.Inflate(20, -10);
gfx.DrawString(String.Format( pageNbrFooter,0 ),
font, XBrushes.Black, box, format);
}
}
outputDocument.Save(fileName);
return outputDocument;
}
}
}
To invoke the class you would supply your stream in place of the pdf and the relative path. Here is a simple hard-coded path example.
Stream[] streams = new Stream[5];
streams[0] = new FileStream(@."c:/Lynette/portrait1.pdf", FileMode.Open);
streams[1] = new FileStream(@."c:/Lynette/portrait2.pdf", FileMode.Open);
streams[2] = new FileStream(@."c:/Lynette/portrait3.pdf", FileMode.Open);
streams[3] = new FileStream(@."c:/Lynette/landscape1.pdf", FileMode.Open);
streams[4] = new FileStream(@."c:/Lynette/portrait4.pdf", FileMode.Open);
PdfDocument combinedPdf = CombinePdfs.combine(streams,"c:/Lynette/myCombined.pdf");
|||
The code sample above should have a subscript in brackets but I guess that is also the symbol for an idea. How funny!
Great solution to this issue. Thank you for posting the code!
Combining multiple subreports into a single report
Thanks!
I did check the landscape width for the reports both individualy and in the master report. They all render fine independently. I also tested the report rendering as I added each subreport to the master report. The moment I added the Landscape one, all portrait reports (that rendered fine before) spilled over onto subsequent pages. The subreports are embedded in a main report and not linked. Can you tell me more about how you configured your reports to be linked?
Thanks!
|||I appologize I meant reducing the body width to portrait regardless of the fact that you have reports set to landscape. I believe at runtime the report server will expand the body width as needed.
A linked report is essentially a smart pointer to the actual report. You can create a linked reportin in the Report Manager. Go to the report properties and click on the Create Linked Report button. The advantage of having this point of indirection is that if the standalone report is moved, the linked report will automatically be redirected to the new location. Also, a linked report can have its own security policies, etc.
|||Hi,
I was able to find information at this link:
http://msdn2.microsoft.com/en-us/library/ms155993.aspx
"Reporting Services does not provide a way to combine landscape and portrait mode pages in the same report, nor does it provide a way to create a print-based layout that replaces or exists alongside the layout of a report as rendered in a browser or other application. For most exported reports, report printouts include everything that is visible on the report, as viewed by the user on a computer monitor."
Not what I wanted to hear. Also, I was unable to find the Linked Reports option within Report Designer Report Properties. We are using Visual Studio 2005. Someone on the team provided these links for combining PDFs. This seems like a lot of work to go thru because of a missing feature. Even Word allows you to insert section breaks where you can specigy Landscapre or Portrait.
http://www.codeproject.com/cs/library/giospdfnetlibrary.asp
https://secure.codeproject.com/csharp/giospdfsplittermerger.asp
|||Yes, this is correct. I appologize for giving you wrong information. Upon looking at our report package implementation, the master report width is set to Landscape. The Create Linked Report button is on the report properties (General Tab) assuming you use the Report Manager and have rights to create linked reports.
|||Hi,
The mechanism that we've used to achieve this is to write some code using a PDF library to combine the reports. It goes off and renders the reports and then adds them to a master document. That way we can add page numbers, table of contents etc. and its all dynamic.
Sanjay
|||Hi, and thanks.
That is what we ended up doing and I am posting the code for the benefit of others. We used PDFSharp (there are several others) and I modified one of their samples into the class below. It worked good and we ended up with one report that could have both landscape and portrait pages and page numbers.
#region PDFsharp - A .NET library for processing PDF
//
// Copyright (c) 2005-2006 empira Software GmbH, Cologne (Germany)
//
// http://www.pdfsharp.com
//
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.IO;
using PdfSharp;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
using PdfSharp.Drawing;
namespace successionManagement
{
public class CombinePdfs
{
public static PdfDocument combine(Stream[] streams, String fileName)
{
PdfDocument outputDocument = new PdfDocument();
XFont font = new XFont("arial", 8, XFontStyle.Regular);
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Center;
format.LineAlignment = XLineAlignment.Far;
XGraphics gfx;
XRect box;
int totalPages = 0;
int currentPage = 0;
PdfDocument[] pdfDocuments = new PdfDocument[streams.Length];
for (int i = 0; i < streams.Length; i++)
{
Stream stream = (Stream) streams;
PdfDocument inputDocument = PdfReader.Open(stream, PdfDocumentOpenMode.Import);
totalPages = totalPages + inputDocument.PageCount;
pdfDocuments = inputDocument;
}
String pageNbrFooter;
for (int i=0; i < pdfDocuments.Length; i++)
{
PdfDocument inputDocument = (PdfDocument) pdfDocuments;
for (int idx = 0; idx < inputDocument.PageCount; idx++)
{
PdfPage page = inputDocument.Pages[idx];
currentPage = currentPage + 1;
pageNbrFooter = "Page " + currentPage + " of " + totalPages;
page = outputDocument.AddPage(page);
//Write document file name and page number on each page
gfx = XGraphics.FromPdfPage(page);
box = page.MediaBox.ToXRect();
box.Inflate(20, -10);
gfx.DrawString(String.Format( pageNbrFooter,0 ),
font, XBrushes.Black, box, format);
}
}
outputDocument.Save(fileName);
return outputDocument;
}
}
}
To invoke the class you would supply your stream in place of the pdf and the relative path. Here is a simple hard-coded path example.
Stream[] streams = new Stream[5];
streams[0] = new FileStream(@."c:/Lynette/portrait1.pdf", FileMode.Open);
streams[1] = new FileStream(@."c:/Lynette/portrait2.pdf", FileMode.Open);
streams[2] = new FileStream(@."c:/Lynette/portrait3.pdf", FileMode.Open);
streams[3] = new FileStream(@."c:/Lynette/landscape1.pdf", FileMode.Open);
streams[4] = new FileStream(@."c:/Lynette/portrait4.pdf", FileMode.Open);
PdfDocument combinedPdf = CombinePdfs.combine(streams,"c:/Lynette/myCombined.pdf");
|||
The code sample above should have a subscript in brackets but I guess that is also the symbol for an idea. How funny!
Great solution to this issue. Thank you for posting the code!