Concatenate PDF documents in C#
Overview
This article explains how to merge, combine or concatenate different PDF files into single PDF using C#. It covers topics e.g.
- C# Merge PDF Files
- C# Combine PDF Files
- C# Merge Multiple PDF files into one PDF
- C# Combine Multiple PDF files into one PDF
- C# Merge all PDF files in a folder
- C# Combine all PDF files in a folder
- C# Merge PDF files using file paths
- C# Combine PDF files using streams
- C# Concatenate all PDF files in folder
Concatenate PDF files using file paths
PdfFileEditor is the class in Aspose.Pdf.Facades namespace which allows you to concatenate multiple PDF files. You can not only concatenate files using FileStreams but also using MemoryStreams as well. In this article, the process of concatenating the files using MemoryStreams will be explained and then shown using the code snippet.
Concatenate method of PdfFileEditor class can be used to concatenate two PDF files. The Concatenate method allows you to pass three parameters: first input PDF, second input PDF, and output PDF. The final output PDF contains both the input PDF files.
The following C# code snippet shows you how to concatenate PDF files using file paths.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenatePdfFilesUsingFilePaths()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Create PdfFileEditor object
var pdfEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// Concatenate files
pdfEditor.Concatenate(dataDir + "ConcatenatePdfFilesUsingFilePaths1.pdf", dataDir + "ConcatenatePdfFilesUsingFilePaths2.pdf", dataDir + "ConcatenateUsingPath_out.pdf");
}
In some cases, when there are a lot of outlines, users may disable them with setting CopyOutlines to false and improve performance of concatenation.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenatePdfFilesUsingFilePaths_CopyOutlinesDisabled()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Create PdfFileEditor object
var pfe = new Aspose.Pdf.Facades.PdfFileEditor();
// Setting CopyOutlines to false
pfe.CopyOutlines = false;
// Concatenate files
pfe.Concatenate(dataDir + "ConcatenatePdfFilesUsingFilePaths_CopyOutlinesDisabled1.pdf", dataDir + "ConcatenatePdfFilesUsingFilePaths_CopyOutlinesDisabled2.pdf", dataDir + "ConcatenateUsingPath_CopyOutlinesDisabled_out.pdf");
}
Concatenate multiple PDF files using MemoryStreams
Concatenate method of PdfFileEditor class takes the source PDF files and the destination PDF file as parameters. These parameters can be either paths to the PDF files on the disk or they could be MemoryStreams. Now, for this example, we’ll first create two files streams to read the PDF files from the disk. Then we’ll convert these files into byte arrays. These byte arrays of the PDF files will be converted to MemoryStreams. Once we get the MemoryStreams out of PDF files, we’ll be able to pass them on to the concatenate method and merge into a single output file.
The following C# code snippet shows you how to concatenate multiple PDF files using MemoryStreams:
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenateMultiplePdfFilesUsingMemoryStreams()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
string document1Path = dataDir + "ConcatenateMultiplePdfFilesUsingMemoryStreams1.pdf";
string document2Path = dataDir + "ConcatenateMultiplePdfFilesUsingMemoryStreams2.pdf";
string resultPdfPath = dataDir + "concatenated_out.pdf";
// Create two file streams to read PDF files
using (var fs1 = new FileStream(document1Path, FileMode.Open, FileAccess.Read))
{
using (var fs2 = new FileStream(document2Path, FileMode.Open, FileAccess.Read))
{
// Create byte arrays to keep the contents of PDF files
var buffer1 = new byte[Convert.ToInt32(fs1.Length)];
var buffer2 = new byte[Convert.ToInt32(fs2.Length)];
var i = 0;
// Read PDF file contents into byte arrays
i = fs1.Read(buffer1, 0, Convert.ToInt32(fs1.Length));
i = fs2.Read(buffer2, 0, Convert.ToInt32(fs2.Length));
// Now, first convert byte arrays into MemoryStreams and then concatenate those streams
using (var pdfStream = new MemoryStream())
{
using (var fileStream1 = new MemoryStream(buffer1))
{
using (var fileStream2 = new MemoryStream(buffer2))
{
// Create instance of PdfFileEditor class to concatenate streams
var pdfEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// Concatenate both input MemoryStreams and save to output MemoryStream
pdfEditor.Concatenate(fileStream1, fileStream2, pdfStream);
// Convert MemoryStream back to byte array
var data = pdfStream.ToArray();
// Create a FileStream to save the output PDF file
using (var output = new FileStream(resultPdfPath, FileMode.Create, FileAccess.Write))
{
// Write byte array contents in the output file stream
output.Write(data, 0, data.Length);
}
}
}
}
}
}
}
Concatenate Array of PDF Files Using File Paths
If you want to concatenate multiple PDF files, you can use the overload of the Concatenate method, which allows you to pass an array of PDF files. The final output is saved as a merged file created from all the files in the array.The following C# code snippet shows you how to concatenate array of PDF files using file paths.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenateArrayOfPdfFilesUsingFilePaths()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Create PdfFileEditor
var pdfEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// Array of files
var filesArray = new string[2];
filesArray[0] = dataDir + "Concatenate1.pdf";
filesArray[1] = dataDir + "Concatenate2.pdf";
// Concatenate files
pdfEditor.Concatenate(filesArray, dataDir + "ConcatenateArrayOfPdfFilesUsingFilePaths_out.pdf");
}
Concatenate Array of PDF Files Using Streams
Concatenating an array of PDF files is not limited to only files residing on the disk. You can also concatenate an array of PDF files from streams. If you want to concatenate multiple PDF files, you can use the appropriate overload of the Concatenate method. First, you need to create an array of input streams and one stream for output PDF and then call the Concatenate method. The output will be saved in the output stream.The following C# code snippet shows you how to concatenate array of PDF files using streams.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenateArrayOfPdfFilesUsingStreams()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
var document1Path = dataDir + "Concatenate1.pdf";
var document2Path = dataDir + "Concatenate2.pdf";
var resultPdfPath = dataDir + "ConcatenateArrayOfPdfUsingStreams_out.pdf";
// Create PdfFileEditor object
var pdfEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// Output stream
using (var outputStream = new FileStream(resultPdfPath, FileMode.Create))
{
using (var stream1 = new FileStream(document1Path, FileMode.Open))
{
using (var stream2 = new FileStream(document2Path, FileMode.Open))
{
// Array of streams
var inputStreams = new Stream[2];
inputStreams[0] = stream1;
inputStreams[1] = stream2;
// Concatenate file
pdfEditor.Concatenate(inputStreams, outputStream);
}
}
}
}
Concatenating all Pdf files in Particular folder
You can even read all the Pdf files in a particular folder at runtime and concatenate them, without even knowing the file names. Simply provide the path of directory, which contains the PDF documents, that you would like to concatenate.
Please try using the following C# code snippet to achieve this functionality.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenatingAllPdfFilesInParticularFolder()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Retrieve names of all the Pdf files in a particular Directory
var fileEntries = Directory.GetFiles(dataDir, "*.pdf");
var resultPdfPath = dataDir + "ConcatenatingAllPdfFilesInParticularFolder_out.pdf";
// Instantiate PdfFileEditor object
var pdfEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// Call Concatenate method of PdfFileEditor object to concatenate all input files
// Into a single output file
pdfEditor.Concatenate(fileEntries, resultPdfPath);
}
Concatenate PDF Forms and keep fields names unique
PdfFileEditor class in Aspose.Pdf.Facades namespace offers the capability to concatenate the PDF files. Now, if the Pdf files which are to be concatenated have form fields with similar field names, Aspose.PDF provides the feature to keep the fields in the resultant Pdf file as unique and also you can specify the suffix to make the field names unique. KeepFieldsUnique property of PdfFileEditor as true will make field names unique when Pdf forms are concatenated. Also, UniqueSuffix property of PdfFileEditor can be used to specify the user defined format of the suffix which is added to field name to make it unique when forms are concatenated. This string must contain %NUM%
substring which will be replaced with numbers in the resultant file.
Please see the following simple code snippet to achieve this functionality.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenatePdfFormsAndKeepFieldsUnique()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Set input and output file paths
var inputFile1 = dataDir + "ConcatenatePdfFormsAndKeepFieldsUnique1.pdf";
var inputFile2 = dataDir + "ConcatenatePdfFormsAndKeepFieldsUnique2.pdf";
var outFile = dataDir + "ConcatenatePDFForms_out.pdf";
// Open PDF documents
var fileEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// To keep unique field Id for all the fields
fileEditor.KeepFieldsUnique = true;
// Format of the suffix which is added to field name to make it unique when forms are concatenated.
fileEditor.UniqueSuffix = "_%NUM%";
// Concatenate the files into a resultant Pdf file
fileEditor.Concatenate(inputFile1, inputFile2, outFile);
}
Concatenate PDF files and create Table Of Contents
Concatenate PDF files
Please take a look over following code snippet for information on how to merge the PDF files.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenatePdfFiles()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Set input and output file paths
var inputFile1 = dataDir + "ConcatenateInput1.pdf";
var inputFile2 = dataDir + "ConcatenateInput2.pdf";
var outFile = dataDir + "ConcatenatePdfFilesAndCreateTOC_out.pdf";
// Create PdfFileEditor object
var pdfEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// Open PDF documents
using (var outputStream = new FileStream(outFile, FileMode.Create))
{
using (var stream1 = new FileStream(inputFile1, FileMode.Open))
{
using (var stream2 = new FileStream(inputFile2, FileMode.Open))
{
// Save concatenated output file
pdfEditor.Concatenate(stream1, stream2, outputStream);
}
}
}
}
Insert blank page
Once the PDF files have been merged, we can insert a blank page at the beginning of document on which can can create Table Of contents. In order to accomplish this requirement, we can load the merged file into Document object and we need to call Page.Insert(…) method to insert a blank page.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void InsertBlankPage()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Insert a blank page at the beginning of concatenated file to display Table of Contents
using (var document = new Aspose.Pdf.Document(dataDir + "ConcatenatePdfFilesAndCreateTOC_out.pdf"))
{
// Insert a blank page in a PDF
document.Pages.Insert(1);
}
}
Add Text Stamps
In order to create a Table of Contents, we need to add Text stamps on first page using PdfFileStamp and Stamp objects. Stamp class provides BindLogo(...)
method to add FormattedText and we can also specify the location to add these text stamps using SetOrigin(..)
method. In this article, we are concatenating two PDF files, so we need to create two text stamp objects pointing to these individual documents.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void AddTextStampForTableOfContents()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
var inputPdfFile = Path.Combine(dataDir, "ConcatenateInput1.pdf");
// Set Text Stamp to display string Table Of Contents
var stamp = new Aspose.Pdf.Facades.Stamp();
stamp.BindLogo(new Aspose.Pdf.Facades.FormattedText("Table Of Contents", System.Drawing.Color.Maroon, System.Drawing.Color.Transparent, Aspose.Pdf.Facades.FontStyle.Helvetica, Aspose.Pdf.Facades.EncodingType.Winansi, true, 18));
// Specify the origin of Stamp. We are getting the page width and specifying the X coordinate for stamp
stamp.SetOrigin(new Aspose.Pdf.Facades.PdfFileInfo(inputPdfFile).GetPageWidth(1) / 3, 700);
// Set particular pages
stamp.Pages = new[] { 1 };
}
Create local links
Now we need to add links towards the pages inside the concatenated file. In order to accomplish this requirement, we can use CreateLocalLink(..)
method of PdfContentEditor class. In following code snippet, we have passed Transparent as 4th argument so that the rectangle around link is not visible.
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void CreateLocalLinks()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Now we need to add Heading for Table Of Contents and links for documents
var contentEditor = new Aspose.Pdf.Facades.PdfContentEditor();
// Bind PDF document
contentEditor.BindPdf(dataDir + "ConcatenatePdfFilesAndCreateTOC_out.pdf");
// Create link for first document
contentEditor.CreateLocalLink(new System.Drawing.Rectangle(150, 650, 100, 20), 2, 1, System.Drawing.Color.Transparent);
}
Complete code
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void CompleteCode()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Create PdfFileEditor object
var pdfEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// Create a MemoryStream object to hold the resultant PDf file
using (var concatenatedStream = new MemoryStream())
{
using (var fs1 = new FileStream(dataDir + "ConcatenateInput1.pdf", FileMode.Open))
{
using (var fs2 = new FileStream(dataDir + "ConcatenateInput2.pdf", FileMode.Open))
{
// Save concatenated output file
pdfEditor.Concatenate(fs1, fs2, concatenatedStream);
}
}
using (var concatenatedPdfDocument = new Aspose.Pdf.Document(concatenatedStream))
{
// Insert a blank page at the beginning of concatenated file to display Table of Contents
concatenatedPdfDocument.Pages.Insert(1);
// Hold the result file with empty page added
using (var documentWithBlankPage = new MemoryStream())
{
// Save PDF document
concatenatedPdfDocument.Save(documentWithBlankPage);
using (var documentWithTocHeading = new MemoryStream())
{
// Add Table Of Contents logo as stamp to PDF file
var fileStamp = new Aspose.Pdf.Facades.PdfFileStamp();
// Bind PDF document
fileStamp.BindPdf(documentWithBlankPage);
// Set Text Stamp to display string Table Of Contents
var stamp = new Aspose.Pdf.Facades.Stamp();
stamp.BindLogo(new Aspose.Pdf.Facades.FormattedText("Table Of Contents", System.Drawing.Color.Maroon, System.Drawing.Color.Transparent,
Aspose.Pdf.Facades.FontStyle.Helvetica, Aspose.Pdf.Facades.EncodingType.Winansi, true, 18));
// Specify the origin of Stamp. We are getting the page width and specifying the X coordinate for stamp
stamp.SetOrigin(new Aspose.Pdf.Facades.PdfFileInfo(documentWithBlankPage).GetPageWidth(1) / 3, 700);
// Set particular pages
stamp.Pages = new[] { 1 };
// Add stamp to PDF file
fileStamp.AddStamp(stamp);
// Create stamp text for first item in Table Of Contents
var document1Link = new Aspose.Pdf.Facades.Stamp();
document1Link.BindLogo(new Aspose.Pdf.Facades.FormattedText("1 - Link to Document 1", System.Drawing.Color.Black, System.Drawing.Color.Transparent,
Aspose.Pdf.Facades.FontStyle.Helvetica, Aspose.Pdf.Facades.EncodingType.Winansi, true, 12));
// Specify the origin of Stamp. We are getting the page width and specifying the X coordinate for stamp
document1Link.SetOrigin(150, 650);
// Set particular pages on which stamp should be displayed
document1Link.Pages = new[] { 1 };
// Add stamp to PDF file
fileStamp.AddStamp(document1Link);
// Create stamp text for second item in Table Of Contents
var document2Link = new Aspose.Pdf.Facades.Stamp();
document2Link.BindLogo(new Aspose.Pdf.Facades.FormattedText("2 - Link to Document 2", System.Drawing.Color.Black, System.Drawing.Color.Transparent,
Aspose.Pdf.Facades.FontStyle.Helvetica, Aspose.Pdf.Facades.EncodingType.Winansi, true, 12));
// Specify the origin of Stamp. We are getting the page width and specifying the X coordinate for stamp
document2Link.SetOrigin(150, 620);
// Set particular pages on which stamp should be displayed
document2Link.Pages = new[] { 1 };
// Add stamp to PDF file
fileStamp.AddStamp(document2Link);
// Save PDF document
fileStamp.Save(documentWithTocHeading);
fileStamp.Close();
// Now we need to add Heading for Table Of Contents and links for documents
var contentEditor = new Aspose.Pdf.Facades.PdfContentEditor();
// Bind PDF document
contentEditor.BindPdf(documentWithTocHeading);
// Create link for first document
contentEditor.CreateLocalLink(new System.Drawing.Rectangle(150, 650, 100, 20), 2, 1, System.Drawing.Color.Transparent);
// Create link for Second document
// We have used new PdfFileInfo("d:/pdftest/Input1.pdf").NumberOfPages + 2 as PdfFileInfo.NumberOfPages(..) returns the page count for first document
// And 2 is because, second document will start at Input1+1 and 1 for the page containing Table Of Contents.
contentEditor.CreateLocalLink(new System.Drawing.Rectangle(150, 620, 100, 20),
new Aspose.Pdf.Facades.PdfFileInfo(dataDir + "ConcatenateInput1.pdf").NumberOfPages + 2, 1, System.Drawing.Color.Transparent);
// Save PDF document
contentEditor.Save(dataDir + "Concatenated_Table_Of_Contents_out.pdf");
}
}
}
}
}
Concatenate PDF files in folder
PdfFileEditor class in Aspose.Pdf.Facades namespace offers you the capability to concatenate the PDF file. You can even read all the Pdf files in a particular folder at runtime and concatenate them, without even knowing the file names. Simply provide the path of directory, which contains the PDF documents, that you would like to concatenate.
Please try using the following C# code snippet to achieve this functionality from Aspose.PDF:
// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConcatenatePdfFilesInFolder()
{
// The path to the documents directory
var dataDir = RunExamples.GetDataDir_AsposePdfFacades_Concatenate();
// Retrieve names of all the Pdf files in a particular Directory
string[] fileEntries = Directory.GetFiles(dataDir, "*.pdf");
// Create PdfFileEditor
var pdfEditor = new Aspose.Pdf.Facades.PdfFileEditor();
// Call Concatenate method of PdfFileEditor object to concatenate all input files
// Into a single output file
pdfEditor.Concatenate(fileEntries, dataDir + "ConcatenatePdfFilesInFolder_out.pdf");
}