Introduction
There are a couple of PDF mergers available on the Internet. But, either they are commercial products or don't support printing of the header and/or footer text, which is particularly interesting, e.g., to print the page number.
Background
The presented PDF merger uses the open source PDF library iTextSharp to process PDF files. The sample solution also includes a tiny Windows Forms application to demonstrate the functionality.
Using the code
For the merge process, the PDF library takes advantage of the PDF page events of the iTextSharp.text.pdf.PdfWriter
object. During the initialization of the PdfPageEvent
instance (which inherits from iTextSharp.text.pdf.IPdfPageEvent
), necessary information for the header/footer text could be passed in to the constructor call:
<s>writer.PageEvent = new PdfPageEvents();</s>
It is important that the header and the footer text, both, are rendered in the 'public void OnEndPage(PdfWriter writer, Document document)
' method. The 'public void OnStartPage(PdfWriter writer, Document document)
' is not accurate.
For performance reasons, this library is now leveraging the PdfCopy class from the iTextSharp library instead of the described method above.
Even though the shown sample is very basic, it generally gives a good overview of how the header and the footer can be populated, e.g., with picture(s), text(s)...
The source code
using System;
using System.Collections.Generic;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace HelveticSolutions.PdfLibrary
{
public static class PdfMerger
{
public static byte[] MergeFiles(List<byte[]> sourceFiles)
{
Document document = new Document();
using (MemoryStream ms = new MemoryStream())
{
PdfCopy copy = new PdfCopy(document, ms);
document.Open();
int documentPageCounter = 0;
for (int fileCounter = 0; fileCounter < sourceFiles.Count; fileCounter++)
{
PdfReader reader = new PdfReader(sourceFiles[fileCounter]);
int numberOfPages = reader.NumberOfPages;
for (int currentPageIndex = 1; currentPageIndex <= numberOfPages; currentPageIndex++)
{
documentPageCounter++;
PdfImportedPage importedPage = copy.GetImportedPage(reader, currentPageIndex);
PdfCopy.PageStamp pageStamp = copy.CreatePageStamp(importedPage);
ColumnText.ShowTextAligned(pageStamp.GetOverContent(), Element.ALIGN_CENTER,
new Phrase("PDF Merger by Helvetic Solutions"), importedPage.Width / 2, importedPage.Height - 30,
importedPage.Width < importedPage.Height ? 0 : 1);
ColumnText.ShowTextAligned(pageStamp.GetOverContent(), Element.ALIGN_CENTER,
new Phrase(String.Format("Page {0}", documentPageCounter)), importedPage.Width / 2, 30,
importedPage.Width < importedPage.Height ? 0 : 1);
pageStamp.AlterContents();
copy.AddPage(importedPage);
}
copy.FreeReader(reader);
reader.Close();
}
document.Close();
return ms.GetBuffer();
}
}
}
}
History
- 01.08.2008 - Article created.
- 17.11.2014 - Updated implementation based on other user's feedback.