Click here to Skip to main content
11,496,146 members (349 online)
Click here to Skip to main content

Simple .NET PDF Merger

, 17 Nov 2014 GPL3 119.6K 7.4K 91
A simple .NET PDF merger that supports header and footer text.
The site is currently in read-only mode for maintenance. Posting of new items will be available again shortly.

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(/*Any type of information goes here*/);</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
    {
        /// <summary>
        /// Merge pdf files.
        /// </summary>
        /// <param name="sourceFiles">PDF files being merged.</param>
        /// <returns></returns>
        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;

                // Iterate through all pdf documents
                for (int fileCounter = 0; fileCounter < sourceFiles.Count; fileCounter++)
                {
                    // Create pdf reader
                    PdfReader reader = new PdfReader(sourceFiles[fileCounter]);
                    int numberOfPages = reader.NumberOfPages;

                    // Iterate through all pages
                    for (int currentPageIndex = 1; currentPageIndex <= numberOfPages; currentPageIndex++)
                    {
                        documentPageCounter++;
                        PdfImportedPage importedPage = copy.GetImportedPage(reader, currentPageIndex);
                        PdfCopy.PageStamp pageStamp = copy.CreatePageStamp(importedPage);

                        // Write header
                        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);

                        // Write footer
                        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.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Michael Ulmann
Architect Helvetic Solutions
Australia Australia
MCAD, MCPD Web Developer 2.0, MCPD Enterprise Developer 3.5

My company: Helvetic Solutions
My blog: Sitecore Experts

Hopp Schwiiz Smile | :)

Comments and Discussions

 
QuestionCorrupt PDFs Pin
Member 1153641912-May-15 10:37
memberMember 1153641912-May-15 10:37 
QuestionFile size seems large Pin
Joel WZ20-Apr-15 10:45
memberJoel WZ20-Apr-15 10:45 
QuestionThank you for your work Pin
araczynski230-Jan-15 12:33
memberaraczynski230-Jan-15 12:33 
QuestionCannot download your sample project Pin
fredatcodeproject17-Nov-14 2:50
memberfredatcodeproject17-Nov-14 2:50 
AnswerRe: Cannot download your sample project Pin
Michael Ulmann17-Nov-14 12:34
memberMichael Ulmann17-Nov-14 12:34 
GeneralRe: Cannot download your sample project Pin
fredatcodeproject17-Nov-14 22:49
memberfredatcodeproject17-Nov-14 22:49 
SuggestionWorks....usually Pin
FlindianaJones7-Nov-14 11:57
memberFlindianaJones7-Nov-14 11:57 
GeneralRe: Works....usually Pin
Michael Ulmann13-Nov-14 20:07
memberMichael Ulmann13-Nov-14 20:07 
GeneralRe: Works....usually Pin
Michael Ulmann16-Nov-14 14:32
memberMichael Ulmann16-Nov-14 14:32 
QuestionMerge Pin
Member 1019053616-Oct-14 6:36
memberMember 1019053616-Oct-14 6:36 
AnswerRe: Merge Pin
Michael Ulmann16-Nov-14 14:30
memberMichael Ulmann16-Nov-14 14:30 
QuestionThank you Pin
Tammam Koujan1-Oct-14 5:34
professionalTammam Koujan1-Oct-14 5:34 
AnswerRe: Thank you Pin
Michael Ulmann3-Nov-14 13:50
memberMichael Ulmann3-Nov-14 13:50 
GeneralMy vote of 3 Pin
Sunil Kumar P21-Sep-14 0:49
memberSunil Kumar P21-Sep-14 0:49 
GeneralRe: My vote of 3 Pin
Michael Ulmann13-Nov-14 20:08
memberMichael Ulmann13-Nov-14 20:08 
GeneralMy vote of 5 Pin
Tyler Forsythe30-Jul-14 12:23
memberTyler Forsythe30-Jul-14 12:23 
GeneralRe: My vote of 5 Pin
Michael Ulmann13-Nov-14 20:08
memberMichael Ulmann13-Nov-14 20:08 
Bugunable to open merged pdf Pin
DevXYZ18-Jul-14 2:01
memberDevXYZ18-Jul-14 2:01 
GeneralRe: unable to open merged pdf Pin
Michael Ulmann16-Nov-14 14:33
memberMichael Ulmann16-Nov-14 14:33 
QuestionMerged document always asks to be saved Pin
Ray Mitchell8-Jun-14 20:00
memberRay Mitchell8-Jun-14 20:00 
AnswerRe: Merged document always asks to be saved Pin
Member 365110127-Jul-14 21:05
memberMember 365110127-Jul-14 21:05 
GeneralThanx Pin
PRABHUSUN7-May-14 2:34
memberPRABHUSUN7-May-14 2:34 
GeneralRe: Thanx Pin
Michael Ulmann13-Nov-14 20:08
memberMichael Ulmann13-Nov-14 20:08 
QuestionBlank pages - SQL report PDF Pin
Garethfr3-Oct-13 6:54
memberGarethfr3-Oct-13 6:54 
AnswerRe: Blank pages - SQL report PDF [modified] Pin
Member 1077258924-Apr-14 7:27
memberMember 1077258924-Apr-14 7:27 
QuestionHelp for merging fillable PDF with regular PDF Pin
dfaber512-Jul-13 15:00
memberdfaber512-Jul-13 15:00 
QuestionCrop/Rotate Pin
Corbin de Bruin25-Apr-13 7:45
memberCorbin de Bruin25-Apr-13 7:45 
Questionneed help for security Pin
Hanieef12-Mar-13 16:17
memberHanieef12-Mar-13 16:17 
GeneralUpvoted - Pin
John Atten26-Jan-13 4:07
memberJohn Atten26-Jan-13 4:07 
GeneralRe: Upvoted - Pin
Michael Ulmann13-Nov-14 20:09
memberMichael Ulmann13-Nov-14 20:09 
GeneralMy vote of 5 Pin
jafarkofahi5-Sep-12 6:52
memberjafarkofahi5-Sep-12 6:52 
GeneralRe: My vote of 5 Pin
Michael Ulmann13-Nov-14 20:10
memberMichael Ulmann13-Nov-14 20:10 
QuestionGreat! Pin
AleBrozzo20-Mar-12 19:51
memberAleBrozzo20-Mar-12 19:51 
AnswerRe: Great! Pin
Michael Ulmann13-Nov-14 20:10
memberMichael Ulmann13-Nov-14 20:10 
QuestionTHANK YOU! Pin
Member 340683825-Jan-12 6:04
memberMember 340683825-Jan-12 6:04 
I was able to implement your code quite easily into my web app, thank you for saving my balding head.
AnswerRe: THANK YOU! Pin
Michael Ulmann18-Mar-12 14:06
memberMichael Ulmann18-Mar-12 14:06 
GeneralRe: THANK YOU! Pin
Member 987752922-Sep-13 23:47
memberMember 987752922-Sep-13 23:47 
GeneralMy vote of 5 Pin
juniorsebr22-Jul-10 3:37
memberjuniorsebr22-Jul-10 3:37 
GeneralRe: My vote of 5 Pin
Michael Ulmann13-Nov-14 20:11
memberMichael Ulmann13-Nov-14 20:11 
GeneralPdfContentByte has a method called ShowTextAligned Pin
RubyPdf25-May-10 14:28
memberRubyPdf25-May-10 14:28 
GeneralInformative article Pin
suraj mehare2-Mar-10 8:06
membersuraj mehare2-Mar-10 8:06 
GeneralRe: Informative article Pin
Michael Ulmann2-Mar-10 20:02
memberMichael Ulmann2-Mar-10 20:02 
QuestionHow to bookmark by each PDF creation time Pin
orlandito2030-Apr-09 23:08
memberorlandito2030-Apr-09 23:08 
QuestionHow to bookmark by each PDF file name Pin
Saam_cse27-Nov-08 23:49
memberSaam_cse27-Nov-08 23:49 
AnswerRe: How to bookmark by each PDF file name Pin
Michael Ulmann1-Dec-08 12:25
memberMichael Ulmann1-Dec-08 12:25 
GeneralRe: How to bookmark by each PDF file name Pin
Saam_cse2-Dec-08 0:23
memberSaam_cse2-Dec-08 0:23 
GeneralRe: How to bookmark by each PDF file name Pin
friendmastor25-Aug-09 16:24
memberfriendmastor25-Aug-09 16:24 
QuestionMerge Large Amount of files Pin
astaykov7-Aug-08 2:02
memberastaykov7-Aug-08 2:02 
AnswerRe: Merge Large Amount of files Pin
Michael Ulmann7-Aug-08 13:52
memberMichael Ulmann7-Aug-08 13:52 
QuestionHow to pass arguments Pin
Väinölä Harri1-Aug-08 4:10
memberVäinölä Harri1-Aug-08 4:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150520.1 | Last Updated 17 Nov 2014
Article Copyright 2008 by Michael Ulmann
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid