Объединение PDF документов в C#

Обзор

Эта статья объясняет, как объединить, комбинировать или склеить разные PDF файлы в один PDF с использованием C#. Она охватывает такие темы, как

Объединение PDF файлов, используя пути к файлам

PdfFileEditor это класс в Aspose.Pdf.Facades namespace, который позволяет объединять несколько PDF файлов. Вы можете не только объединять файлы с помощью FileStreams, но и использовать MemoryStreams. В этой статье будет объяснен процесс объединения файлов с использованием MemoryStreams, а затем показан с помощью примера кода.

Метод Concatenate класса PdfFileEditor может быть использован для объединения двух PDF-файлов. Метод Concatenate позволяет передать три параметра: первый входной PDF, второй входной PDF и выходной PDF. Итоговый выходной PDF содержит оба входных PDF-файла.

Следующий пример кода на C# показывает, как объединить PDF-файлы, используя пути к файлам.

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_Pages();
// Create PdfFileEditor object
PdfFileEditor pdfEditor = new PdfFileEditor();
// Concatenate files
pdfEditor.Concatenate(dataDir + "input.pdf", dataDir + "input2.pdf", dataDir + "ConcatenateUsingPath_out.pdf");

В некоторых случаях, когда имеется много оглавлений, пользователи могут отключить их, установив CopyOutlines в false, и улучшить производительность объединения.

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_Pages();
PdfFileEditor pfe = new PdfFileEditor();
string[] files = Directory.GetFiles(dataDir);
pfe.CopyOutlines = false;
pfe.Concatenate(files, dataDir + "CopyOutline_out.pdf");

Объединение нескольких PDF-файлов с использованием MemoryStreams

Метод Concatenate класса PdfFileEditor принимает исходные PDF-файлы и PDF-файл назначения в качестве параметров. Эти параметры могут быть либо путями к PDF-файлам на диске, либо они могут быть MemoryStreams. Теперь, для этого примера, мы сначала создадим два потока файлов для чтения PDF-файлов с диска. Затем мы конвертируем эти файлы в массивы байтов. Эти массивы байтов PDF-файлов будут преобразованы в MemoryStreams. Как только мы получим MemoryStreams из PDF-файлов, мы сможем передать их в метод объединения и объединить в один выходной файл.

Следующий фрагмент кода C# показывает, как объединить несколько PDF-файлов с использованием MemoryStreams:

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_TechnicalArticles();
// Create two file streams to read pdf files
FileStream fs1 = new FileStream(dataDir + "inFile.pdf", FileMode.Open, FileAccess.Read);
FileStream fs2 = new FileStream(dataDir + "inFile2.pdf", FileMode.Open, FileAccess.Read);
// Create byte arrays to keep the contents of PDF files
byte[] buffer1 = new byte[Convert.ToInt32(fs1.Length)];
byte[] buffer2 = new byte[Convert.ToInt32(fs2.Length)];
int 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 (MemoryStream pdfStream = new MemoryStream())
{
using (MemoryStream fileStream1 = new MemoryStream(buffer1))
{
using (MemoryStream fileStream2 = new MemoryStream(buffer2))
{
// Create instance of PdfFileEditor class to concatenate streams
PdfFileEditor pdfEditor = new PdfFileEditor();
// Concatenate both input MemoryStreams and save to putput MemoryStream
pdfEditor.Concatenate(fileStream1, fileStream2, pdfStream);
// Convert MemoryStream back to byte array
byte[] data = pdfStream.ToArray();
// Create a FileStream to save the output PDF file
FileStream output = new FileStream(dataDir + "merged_out.pdf", FileMode.Create,
FileAccess.Write);
// Write byte array contents in the output file stream
output.Write(data, 0, data.Length);
// Close output file
output.Close();
}
}
}
// Close input files
fs1.Close();
fs2.Close();

Объединение массива PDF-файлов с использованием путей к файлам

Если вы хотите объединить несколько PDF-файлов, вы можете использовать перегрузку метода Concatenate, которая позволяет передавать массив PDF-файлов. Итоговый результат сохраняется как объединенный файл, созданный из всех файлов в массиве. Следующий фрагмент кода на C# показывает, как объединить массив PDF-файлов, используя пути к файлам.

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_Pages();
// Create PdfFileEditor object
PdfFileEditor pdfEditor = new PdfFileEditor();
// Array of files
string[] filesArray = new string[2];
filesArray[0] = dataDir + "input.pdf";
filesArray[1] = dataDir + "input2.pdf";
// Concatenate files
pdfEditor.Concatenate(filesArray, dataDir + "ConcatenateArrayOfFilesWithPath_out.pdf");

Объединение массива PDF-файлов с использованием потоков

Объединение массива PDF-файлов не ограничивается только файлами, находящимися на диске. Вы также можете объединить массив PDF файлов из потоков. Если вы хотите объединить несколько PDF файлов, вы можете использовать соответствующую перегрузку метода Concatenate. Сначала вам нужно создать массив входных потоков и один поток для выходного PDF, а затем вызвать метод Concatenate. Выходной результат будет сохранен в выходном потоке. Следующий фрагмент кода на C# показывает, как объединить массив PDF файлов, используя потоки.

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_Pages();
// Create PdfFileEditor object
PdfFileEditor pdfEditor = new PdfFileEditor();
// Output stream
FileStream outputStream = new FileStream(dataDir + "ConcatenateArrayOfPdfUsingStreams_out.pdf", FileMode.Create);
// Array of streams
FileStream[] inputStreams = new FileStream[2];
inputStreams[0] = new FileStream(dataDir + "input.pdf", FileMode.Open);
inputStreams[1] = new FileStream(dataDir + "input2.pdf", FileMode.Open);
// Concatenate file
pdfEditor.Concatenate(inputStreams, outputStream);

Объединение всех PDF файлов в определенной папке

Вы даже можете прочитать все PDF файлы в определенной папке во время выполнения и объединить их, даже не зная имен файлов. Предоставьте путь к каталогу, который содержит PDF-документы, которые вы хотите объединить.

Попробуйте использовать следующий фрагмент кода C#, чтобы достичь этой функциональности.

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_TechnicalArticles();
// Retrieve names of all the Pdf files in a particular Directory
string[] fileEntries = Directory.GetFiles(dataDir, "*.pdf");
// Get the current System date and set its format
string date = DateTime.Now.ToString("MM-dd-yyyy");
// Get the current System time and set its format
string hoursSeconds = DateTime.Now.ToString("hh-mm");
// Set the value for the final Resultant Pdf document
string masterFileName = date + "_" + hoursSeconds + "_out.pdf";
// Instantiate PdfFileEditor object
Aspose.Pdf.Facades.PdfFileEditor pdfEditor = new PdfFileEditor();
// Call Concatenate method of PdfFileEditor object to concatenate all input files
// Into a single output file
pdfEditor.Concatenate(fileEntries, dataDir + masterFileName);

Объединение PDF-форм и сохранение уникальности имен полей

Класс PdfFileEditor в пространстве имен Aspose.Pdf.Facades предлагает возможность объединения PDF-файлов. Теперь, если PDF файлы, которые нужно объединить, содержат поля формы с одинаковыми именами полей, Aspose.PDF предоставляет возможность сделать поля в результирующем PDF файле уникальными, а также вы можете указать суффикс, чтобы сделать имена полей уникальными. Свойство KeepFieldsUnique класса PdfFileEditor как true сделает имена полей уникальными при объединении PDF форм. Также свойство UniqueSuffix класса PdfFileEditor может быть использовано для указания пользовательского формата суффикса, который добавляется к имени поля, чтобы сделать его уникальным при объединении форм. Эта строка должна содержать подстроку %NUM%, которая будет заменена на числа в результирующем файле.

Пожалуйста, смотрите следующий простой пример кода для достижения этой функциональности.

Объединение PDF файлов и создание оглавления

Объединение PDF файлов

Пожалуйста, ознакомьтесь с приведенным ниже фрагментом кода, чтобы узнать, как объединять PDF файлы.

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_TechnicalArticles();
// Create PdfFileEditor object
PdfFileEditor pdfEditor = new PdfFileEditor();
// Save concatenated output file
pdfEditor.Concatenate(new FileStream(dataDir + "input1.pdf", FileMode.Open), new FileStream(dataDir + "input2.pdf", FileMode.Open), new FileStream(dataDir + "ConcatenatePdfFilesAndCreateTOC_out.pdf", FileMode.Create));

Вставка пустой страницы

После объединения PDF файлов мы можем вставить пустую страницу в начало документа, на которой можно создать оглавление. Чтобы выполнить это требование, мы можем загрузить объединенный файл в объект Document и вызвать метод Page.Insert(…), чтобы вставить пустую страницу.

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_TechnicalArticles();
// Insert a blank page at the begining of concatenated file to display Table of Contents
Aspose.Pdf.Document concatenated_pdfDocument = new Aspose.Pdf.Document(new FileStream(dataDir + "Concatenated_Table_Of_Contents.pdf", FileMode.Open));
// Insert a empty page in a PDF
concatenated_pdfDocument.Pages.Insert(1);

Добавление текстовых штампов

Для создания оглавления нам необходимо добавить текстовые штампы на первой странице, используя объекты PdfFileStamp и Stamp. Класс Stamp предоставляет метод BindLogo(...) для добавления FormattedText, и мы также можем указать местоположение для добавления этих текстовых штампов с помощью метода SetOrigin(..). В этой статье мы объединяем два PDF-файла, поэтому нам нужно создать два объекта текстовых штампов, указывающих на эти отдельные документы.

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_TechnicalArticles();
// Set Text Stamp to display string Table Of Contents
Aspose.Pdf.Facades.Stamp stamp = new Aspose.Pdf.Facades.Stamp();
stamp.BindLogo(new FormattedText("Table Of Contents", System.Drawing.Color.Maroon, System.Drawing.Color.Transparent, Aspose.Pdf.Facades.FontStyle.Helvetica, 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 PdfFileInfo(new FileStream(dataDir + "input1.pdf", FileMode.Open)).GetPageWidth(1) / 3), 700);
// Set particular pages
stamp.Pages = new int[] { 1 };

Создать локальные ссылки

Теперь нам нужно добавить ссылки на страницы внутри объединенного файла. Чтобы выполнить это требование, мы можем использовать метод CreateLocalLink(..) класса PdfContentEditor. В следующем фрагменте кода мы передали Transparent в качестве 4-го аргумента, чтобы прямоугольник вокруг ссылки не был виден.

### Полный код

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-.NET
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_AsposePdfFacades_TechnicalArticles();
// Create PdfFileEditor object
PdfFileEditor pdfEditor = new PdfFileEditor();
// Create a MemoryStream object to hold the resultant PDf file
using (MemoryStream Concatenated_Stream = new MemoryStream())
{
// Save concatenated output file
pdfEditor.Concatenate(new FileStream(dataDir + "input1.pdf", FileMode.Open), new FileStream(dataDir + "input2.pdf", FileMode.Open), Concatenated_Stream);
// Insert a blank page at the begining of concatenated file to display Table of Contents
Aspose.Pdf.Document concatenated_pdfDocument = new Aspose.Pdf.Document(Concatenated_Stream);
// Insert a empty page in a PDF
concatenated_pdfDocument.Pages.Insert(1);
// Hold the resultnat file with empty page added
using (MemoryStream Document_With_BlankPage = new MemoryStream())
{
// Save output file
concatenated_pdfDocument.Save(Document_With_BlankPage);
using (var Document_with_TOC_Heading = new MemoryStream())
{
// Add Table Of Contents logo as stamp to PDF file
PdfFileStamp fileStamp = new PdfFileStamp();
// Find the input file
fileStamp.BindPdf(Document_With_BlankPage);
// Set Text Stamp to display string Table Of Contents
Aspose.Pdf.Facades.Stamp stamp = new Aspose.Pdf.Facades.Stamp();
stamp.BindLogo(new FormattedText("Table Of Contents", System.Drawing.Color.Maroon, System.Drawing.Color.Transparent, Aspose.Pdf.Facades.FontStyle.Helvetica, 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 PdfFileInfo(Document_With_BlankPage).GetPageWidth(1) / 3), 700);
// Set particular pages
stamp.Pages = new int[] { 1 };
// Add stamp to PDF file
fileStamp.AddStamp(stamp);
// Create stamp text for first item in Table Of Contents
var Document1_Link = new Aspose.Pdf.Facades.Stamp();
Document1_Link.BindLogo(new FormattedText("1 - Link to Document 1", System.Drawing.Color.Black, System.Drawing.Color.Transparent, Aspose.Pdf.Facades.FontStyle.Helvetica, EncodingType.Winansi, true, 12));
// Specify the origin of Stamp. We are getting the page width and specifying the X coordinate for stamp
Document1_Link.SetOrigin(150, 650);
// Set particular pages on which stamp should be displayed
Document1_Link.Pages = new int[] { 1 };
// Add stamp to PDF file
fileStamp.AddStamp(Document1_Link);
// Create stamp text for second item in Table Of Contents
var Document2_Link = new Aspose.Pdf.Facades.Stamp();
Document2_Link.BindLogo(new FormattedText("2 - Link to Document 2", System.Drawing.Color.Black, System.Drawing.Color.Transparent, Aspose.Pdf.Facades.FontStyle.Helvetica, EncodingType.Winansi, true, 12));
// Specify the origin of Stamp. We are getting the page width and specifying the X coordinate for stamp
Document2_Link.SetOrigin(150, 620);
// Set particular pages on which stamp should be displayed
Document2_Link.Pages = new int[] { 1 };
// Add stamp to PDF file
fileStamp.AddStamp(Document2_Link);
// Save updated PDF file
fileStamp.Save(Document_with_TOC_Heading);
fileStamp.Close();
// Now we need to add Heading for Table Of Contents and links for documents
PdfContentEditor contentEditor = new PdfContentEditor();
// Bind the PDF file in which we added the blank page
contentEditor.BindPdf(Document_with_TOC_Heading);
// 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 PdfFileInfo(dataDir + "Input1.pdf").NumberOfPages + 2, 1, System.Drawing.Color.Transparent);
// Save updated PDF
contentEditor.Save( dataDir + "Concatenated_Table_Of_Contents.pdf");
}
}
}
## Объединение PDF файлов в папке Класс [PdfFileEditor](https://reference.aspose.com/pdf/net/aspose.pdf.facades/pdffileeditor) в пространстве имен Aspose.Pdf.Facades предоставляет возможность объединять PDF файлы. Вы можете даже прочитать все PDF файлы в определенной папке во время выполнения и объединить их, даже не зная имен файлов. Просто укажите путь к каталогу, содержащему PDF документы, которые вы хотите объединить. Попробуйте использовать следующий фрагмент кода на C# для достижения этой функциональности с помощью Aspose.PDF: ```csharp // Путь к каталогу документов. string dataDir = RunExamples.GetDataDir_AsposePdfFacades_TechnicalArticles(); // Извлечь имена всех PDF файлов в определенном каталоге string[] fileEntries = Directory.GetFiles(dataDir, "*.pdf"); // Получить текущую системную дату и установить ее формат string date = DateTime.Now.ToString("MM-dd-yyyy"); // Получить текущее системное время и установить его формат string hoursSeconds = DateTime.Now.ToString("hh-mm"); // Установить значение для итогового результирующего PDF документа string masterFileName = date + "_" + hoursSeconds + "_out.pdf"; // Создать экземпляр объекта PdfFileEditor Aspose.Pdf.Facades.PdfFileEditor pdfEditor = new PdfFileEditor(); // Вызвать метод Concatenate объекта PdfFileEditor для объединения всех входных файлов // В один выходной файл pdfEditor.Concatenate(fileEntries, dataDir + masterFileName);