Come unire più file PDF (generati in fase di esecuzione)?

Come unire più file PDF (generati in fase di esecuzione) tramite ItextSharp quindi stamparli.

Ho trovato il seguente link ma quel metodo richiede i nomi pdf considerando che i file pdf sono archiviati e questo non è il mio caso.


Ho più rapporti che li convertirò in pdf files con questo metodo:

 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(); } 

Ora voglio unire tutti i file generati ( Bytes ) in un file pdf per stamparlo

    Se vuoi unire documenti sorgente usando iText (Sharp), ci sono due situazioni base:

    1. Vuoi veramente unire i documenti, acquisire le pagine nel loro formato originale, trasferire il maggior numero ansible di loro contenuti e le loro annotazioni interattive. In questo caso dovresti utilizzare una soluzione basata su un membro della famiglia di classi Pdf*Copy* .

    2. In realtà si desidera integrare le pagine dei documenti di origine in un nuovo documento, ma si vuole che il nuovo documento gestisca il formato generale e non si preoccupi delle funzionalità interattive (annotazioni …) nei documenti originali (o anche di voler eliminare di loro). In questo caso dovresti usare una soluzione basata sulla class PdfWriter .

    Puoi trovare i dettagli nel capitolo 6 (in particolare la sezione 6.4) di iText in Action – 2nd Edition . Qui è ansible accedere al codice di esempio di Java e alle versioni di C # ified.

    Un semplice esempio che utilizza PdfCopy è Concatenate.java / Concatenate.cs . Il pezzo di codice centrale è:

     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(); } 

    Qui il pdf può essere definito come List contenente immediatamente i documenti di origine (appropriato per il tuo caso di unione di documenti intermedi di memoria) o come List contenente i nomi dei file di documento di origine (appropriato se si uniscono documenti dal disco).

    Una panoramica alla fine del capitolo di riferimento riassume l'uso delle classi menzionate:

    • PdfCopy : copia pagine da uno o più documenti PDF esistenti. PdfCopy negativi importanti: PdfCopy non rileva il contenuto ridondante e fallisce quando concatena i moduli.

    • PdfCopyFields : inserisce i campi dei diversi moduli in un unico modulo. Può essere usato per evitare i problemi incontrati con i campi del modulo quando si concatenano i moduli usando PdfCopy . L'utilizzo della memoria può essere un problema.

    • PdfSmartCopy : copia pagine da uno o più documenti PDF esistenti. PdfSmartCopy è in grado di rilevare contenuti ridondanti, ma richiede più memoria e CPU rispetto a PdfCopy .

    • PdfWriter : genera documenti PDF da zero. Può importare pagine da altri documenti PDF. Lo svantaggio principale è che tutte le funzionalità interattive della pagina importata (annotazioni, segnalibri, campi e così via) vengono perse nel processo.

    Ho usato iTextsharp con c # per combinare i file pdf. Questo è il codice che ho usato.

     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; } } 

    Ecco un codice che ho tirato fuori da un vecchio progetto che avevo. Era un’applicazione web, ma stavo usando iTextSharp per unire file PDF e poi stamparli.

     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; } } 

    Non ho scritto questo, ma ho apportato alcune modifiche. Non riesco a ricordare dove l’ho trovato. Dopo aver unito i PDF, chiamerei questo metodo per inserire javascript per aprire la finestra di dialogo di stampa quando viene aperto il PDF. Se si cambia bSilent su true, si dovrebbe stampare in modo silenzioso sulla stampante predefinita.

     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; } 

    Non sono sicuro di quanto bene sia stato scritto il codice sopra da quando l’ho estratto da qualche altra parte e non ho approfondito affatto con iTextSharp, ma so che ha funzionato per unire i PDF che stavo generando in fase di runtime.

    Testato con 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; } } 

    Per evitare i problemi di memoria menzionati, ho utilizzato il stream di file anziché il stream di memoria (menzionato in ITextSharp Eccezione di memoria che unisce più PDF ) per unire file 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)); } } } } } }