Как объединить несколько файлов PDF (сгенерированных во время выполнения)?

Как объединить несколько файлов PDF (сгенерированных во время выполнения) через ItextSharp затем распечатать их.

Я нашел следующую ссылку, но для этого метода требуются имена PDF, учитывая, что хранятся файлы PDF, и это не мое дело.


У меня есть несколько отчетов, которые я буду конвертировать в pdf files помощью этого метода:

 private void AddReportToResponse(LocalReport followsReport) { string mimeType; string encoding; string extension; string[] streams = new string[100]; Warning[] warnings = new Warning[100]; byte[] pdfStream = followsReport.Render("PDF", "", out mimeType, out encoding, out extension, out streams, out warnings); //Response.Clear(); //Response.ContentType = mimeType; //Response.AddHeader("content-disposition", "attachment; filename=Application." + extension); //Response.BinaryWrite(pdfStream); //Response.End(); } 

Теперь я хочу объединить все эти сгенерированные файлы ( Bytes ) в один файл pdf, чтобы напечатать его

    Если вы хотите объединить исходные документы с помощью iText (Sharp), есть две основные ситуации:

    1. Вы действительно хотите объединить документы, приобретая страницы в исходном формате, передавая как можно больше своего контента и своих интерактивных аннотаций. В этом случае вы должны использовать решение, основанное на члене семейства Pdf*Copy* .

    2. Вы действительно хотите интегрировать страницы из исходных документов в новый документ, но хотите, чтобы новый документ управлял общим форматом и не заботился об интерактивных функциях (annotations …) в исходных документах (или даже хотите избавиться из них). В этом случае вы должны использовать решение на PdfWriter classа PdfWriter .

    Подробности вы найдете в главе 6 (особенно в разделе 6.4) iText в действии – 2nd Edition . Здесь можно получить код примера Java, а также здесь версии C #.

    Простой пример с использованием PdfCopy – Concatenate.java / Concatenate.cs . Центральная часть кода:

     byte[] mergedPdf = null; using (MemoryStream ms = new MemoryStream()) { using (Document document = new Document()) { using (PdfCopy copy = new PdfCopy(document, ms)) { document.Open(); for (int i = 0; i < pdf.Count; ++i) { PdfReader reader = new PdfReader(pdf[i]); // loop over the pages in that document int n = reader.NumberOfPages; for (int page = 0; page < n; ) { copy.AddPage(copy.GetImportedPage(reader, ++page)); } } } } mergedPdf = ms.ToArray(); } 

    Здесь pdf может быть определен как List содержащий исходные документы (подходящие для использования вами в случае слияния промежуточных документов в памяти) или в виде List содержащего имена файлов исходного документа (при необходимости вы объединяете документы с диска).

    Обзор в конце упомянутой главы суммирует использование упомянутых classов:

    • PdfCopy : PdfCopy страницы из одного или нескольких существующих документов PDF. Основные недостатки: PdfCopy не обнаруживает избыточный контент, и он не работает при конкатенации форм.

    • PdfCopyFields : Помещает поля разных форм в одну форму. Может использоваться, чтобы избежать проблем, возникающих при PdfCopy полей формы при конкатенации форм с использованием PdfCopy . Использование памяти может быть проблемой.

    • PdfSmartCopy : PdfSmartCopy страницы из одного или нескольких существующих документов PDF. PdfSmartCopy способен обнаруживать избыточный контент, но ему требуется больше памяти и процессора, чем PdfCopy .

    • PdfWriter : PdfWriter PDF-документы с нуля. Может импортировать страницы из других PDF-документов. Основной недостаток заключается в том, что все интерактивные функции импортируемой страницы (annotations, закладки, поля и т. Д.) Теряются в процессе.

    Я использовал iTextsharp с c # для объединения файлов PDF. Это код, который я использовал.

     string[] lstFiles=new string[3]; lstFiles[0][email protected]"C:/pdf/1.pdf"; lstFiles[1][email protected]"C:/pdf/2.pdf"; lstFiles[2][email protected]"C:/pdf/3.pdf"; PdfReader reader = null; Document sourceDocument = null; PdfCopy pdfCopyProvider = null; PdfImportedPage importedPage; string [email protected]"C:/pdf/new.pdf"; sourceDocument = new Document(); pdfCopyProvider = new PdfCopy(sourceDocument, new System.IO.FileStream(outputPdfPath, System.IO.FileMode.Create)); //Open the output file sourceDocument.Open(); try { //Loop through the files list for (int f = 0; f < lstFiles.Length-1; f++) { int pages =get_pageCcount(lstFiles[f]); reader = new PdfReader(lstFiles[f]); //Add pages of current file for (int i = 1; i <= pages; i++) { importedPage = pdfCopyProvider.GetImportedPage(reader, i); pdfCopyProvider.AddPage(importedPage); } reader.Close(); } //At the end save the output file sourceDocument.Close(); } catch (Exception ex) { throw ex; } private int get_pageCcount(string file) { using (StreamReader sr = new StreamReader(File.OpenRead(file))) { Regex regex = new Regex(@"/Type\s*/Page[^s]"); MatchCollection matches = regex.Matches(sr.ReadToEnd()); return matches.Count; } } 

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

     public static class PdfMerger { ///  /// Merge pdf files. ///  /// PDF files being merged. ///  public static byte[] MergeFiles(List sourceFiles) { Document document = new Document(); MemoryStream output = new MemoryStream(); try { // Initialize pdf writer PdfWriter writer = PdfWriter.GetInstance(document, output); writer.PageEvent = new PdfPageEvents(); // Open document to write document.Open(); PdfContentByte content = writer.DirectContent; // 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++) { // Determine page size for the current page document.SetPageSize( reader.GetPageSizeWithRotation(currentPageIndex)); // Create page document.NewPage(); PdfImportedPage importedPage = writer.GetImportedPage(reader, currentPageIndex); // Determine page orientation int pageOrientation = reader.GetPageRotation(currentPageIndex); if ((pageOrientation == 90) || (pageOrientation == 270)) { content.AddTemplate(importedPage, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(currentPageIndex).Height); } else { content.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0); } } } } catch (Exception exception) { throw new Exception("There has an unexpected exception" + " occured during the pdf merging process.", exception); } finally { document.Close(); } return output.GetBuffer(); } } ///  /// Implements custom page events. ///  internal class PdfPageEvents : IPdfPageEvent { #region members private BaseFont _baseFont = null; private PdfContentByte _content; #endregion #region IPdfPageEvent Members public void OnOpenDocument(PdfWriter writer, Document document) { _baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); _content = writer.DirectContent; } public void OnStartPage(PdfWriter writer, Document document) { } public void OnEndPage(PdfWriter writer, Document document) { } public void OnCloseDocument(PdfWriter writer, Document document) { } public void OnParagraph(PdfWriter writer, Document document, float paragraphPosition) { } public void OnParagraphEnd(PdfWriter writer, Document document, float paragraphPosition) { } public void OnChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) { } public void OnChapterEnd(PdfWriter writer, Document document, float paragraphPosition) { } public void OnSection(PdfWriter writer, Document document, float paragraphPosition, int depth, Paragraph title) { } public void OnSectionEnd(PdfWriter writer, Document document, float paragraphPosition) { } public void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, string text) { } #endregion private float GetCenterTextPosition(string text, PdfWriter writer) { return writer.PageSize.Width / 2 - _baseFont.GetWidthPoint(text, 8) / 2; } } 

    Я не писал этого, но внес некоторые изменения. Я не могу вспомнить, где я его нашел. После того, как я объединил PDF-файлы, я бы назвал этот метод, чтобы вставить javascript, чтобы открыть диалоговое окно печати при открытии PDF-файла. Если вы измените значение bSilent на true, оно должно тихо печатать на принтере по умолчанию.

     public Stream addPrintJStoPDF(Stream thePDF) { MemoryStream outPutStream = null; PRStream finalStream = null; PdfDictionary page = null; string content = null; //Open the stream with iTextSharp var reader = new PdfReader(thePDF); outPutStream = new MemoryStream(finalStream.GetBytes()); var stamper = new PdfStamper(reader, (MemoryStream)outPutStream); var jsText = "var res = app.setTimeOut('this.print({bUI: true, bSilent: false, bShrinkToFit: false});', 200);"; //Add the javascript to the PDF stamper.JavaScript = jsText; stamper.FormFlattening = true; stamper.Writer.CloseStream = false; stamper.Close(); //Set the stream to the beginning outPutStream.Position = 0; return outPutStream; } 

    Не уверен, насколько хорошо написанный код написан с тех пор, как я вытащил его из другого места, и я совсем не работал с iTextSharp, но знаю, что он действительно работал при объединении PDF-файлов, которые я генерировал во время выполнения.

    Протестировано iTextSharp-LGPL 4.1.6:

      public static byte[] ConcatenatePdfs(IEnumerable documents) { using (var ms = new MemoryStream()) { var outputDocument = new Document(); var writer = new PdfCopy(outputDocument, ms); outputDocument.Open(); foreach (var doc in documents) { var reader = new PdfReader(doc); for (var i = 1; i <= reader.NumberOfPages; i++) { writer.AddPage(writer.GetImportedPage(reader, i)); } writer.FreeReader(reader); reader.Close(); } writer.Close(); outputDocument.Close(); var allPagesContent = ms.GetBuffer(); ms.Flush(); return allPagesContent; } } 

    Чтобы избежать упомянутых проблем памяти, я использовал stream файлов вместо streamа памяти (упомянутый в исключении ITextSharp Out of memory, объединяющий несколько PDF ) для объединения файлов PDF:

      var parentDirectory = Directory.GetParent(SelectedDocuments[0].FilePath); var savePath = parentDirectory + "\\MergedDocument.pdf"; using (var fs = new FileStream(savePath, FileMode.Create)) { using (var document = new Document()) { using (var pdfCopy = new PdfCopy(document, fs)) { document.Open(); for (var i = 0; i < SelectedDocuments.Count; i++) { using (var pdfReader = new PdfReader(SelectedDocuments[i].FilePath)) { for (var page = 0; page < pdfReader.NumberOfPages;) { pdfCopy.AddPage(pdfCopy.GetImportedPage(pdfReader, ++page)); } } } } } } 
    Давайте будем гением компьютера.