2011-12-05 14 views
6

Tengo cuatro MemoryStreams de datos que deseo fusionar y luego abro el pdfDocument, sin crear un solo archivo.Fusionar flujos de memoria a un documento de iText

Es posible escribirlos en archivos y luego fusionarlos, pero eso sería una mala práctica y eso también puede causar algunos problemas, así que quiero evitar eso.

Sin embargo, no encuentro una manera de combinar MemoryStreams con iText5 para .NET.

En este momento, así es como lo hago con los archivos:

private static void ConcatenateDocuments() 
    { 
     var stream = new MemoryStream(); 

     var readerFrontPage = new PdfReader(Folder + FrontPageName); 
     var readerDocA = new PdfReader(Folder + docA); 
     var readerDocB = new PdfReader(Folder + DocB); 
     var readerAppendix = new PdfReader(Folder + Appendix); 
     var pdfCopyFields = new PdfCopyFields(stream); 

     pdfCopyFields.AddDocument(readerFrontPage); 
     pdfCopyFields.AddDocument(readerDocA); 
     pdfCopyFields.AddDocument(readerDocB); 
     pdfCopyFields.AddDocument(readerAppendix); 
     pdfCopyFields.Close(); 

     SavePdf(stream, FilenameReport); 
    } 

Desde que necesita para eliminar el uso de archivos, guardo la década de MemoryStream como las diferentes piezas se construyen a partir de diferentes recursos. Así que tengo referencias a estos flujos de memoria.

¿Cómo se puede hacer esto?

+0

No se puede usar var readerFrontPage = new PdfReader (yourMemoryStream); – user629926

+1

Esa es la cosa, no puedo hacer que funcione. Uno de los errores que encuentro es "No se encontró la firma del encabezado PDF". Sin embargo, la mayoría de las personas que se topan con este problema usan archivos, y esa no es una opción aquí. – Johan

+0

Mientras que las costuras del PdfReader no pueden tomar la corriente, la matriz de la secuencia funciona. var readerFrontPage = new PdfReader (streamFrontPage.ToArray()); Tú no puedo responder mi propia pregunta aún ... – Johan

Respuesta

18

El error PDF header signature not found se puede solucionar en este caso estableciendo el Position de la secuencia de nuevo en 0. Como no obtiene el error Cannot access a closed Stream supongo que ya está configurando correctamente PdfWriter 's CloseStream en false.

A continuación se muestra una aplicación WinForm C# 2010 que funciona en su totalidad con iTextSharp 5.1.1.0 que crea tres archivos PDF en MemoryStreams y los combina. Como no tengo un servidor web a mano, los estoy escribiendo en el disco.

using System; 
using System.Text; 
using System.Windows.Forms; 
using System.IO; 
using iTextSharp.text; 
using iTextSharp.text.pdf; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      //Create three MemoryStreams 
      MemoryStream[] streams = { CreateDoc("Page 1"), CreateDoc("Page 2"), CreateDoc("Page 3") }; 

      //I don't have a web server handy so I'm going to write my final MemoryStream to a byte array and then to disk 
      byte[] bytes; 

      //Create our final combined MemoryStream 
      using (MemoryStream finalStream = new MemoryStream()) 
      { 
       //Create our copy object 
       PdfCopyFields copy = new PdfCopyFields(finalStream); 

       //Loop through each MemoryStream 
       foreach (MemoryStream ms in streams) 
       { 
        //Reset the position back to zero 
        ms.Position = 0; 
        //Add it to the copy object 
        copy.AddDocument(new PdfReader(ms)); 
        //Clean up 
        ms.Dispose(); 
       } 
       //Close the copy object 
       copy.Close(); 

       //Get the raw bytes to save to disk 
       bytes = finalStream.ToArray(); 
      } 

      //Write out the file to the desktop 
      string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Combined.pdf"); 
      using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) 
      { 
       fs.Write(bytes, 0, bytes.Length); 
      } 

      this.Close(); 
     } 

     /// <summary> 
     /// Helper method to create temporary documents 
     /// </summary> 
     private MemoryStream CreateDoc(string name) 
     { 
      MemoryStream ms = new MemoryStream(); 
      using (Document doc = new Document(PageSize.LETTER)) 
      { 
       using (PdfWriter writer = PdfWriter.GetInstance(doc, ms)) 
       { 
        writer.CloseStream = false; 
        doc.Open(); 
        doc.Add(new Paragraph(name)); 
        doc.Close(); 
       } 
      } 
      return ms; 
     } 
    } 
} 
+1

Perfecto. En mi caso, yo estaba haciendo 'stream.Position = 0' pero en el lugar equivocado: dentro de la declaración' using'. Después de moverlo afuera funciona muy bien. Por cierto Chris: felicitaciones por ayudar a la comunidad cuando se trata de iTextSharp. ¡Dios te bendiga! :) –

+0

Gracias, trabajando para mí al recordar establecer CloseStream en falso en el escritor y llamar a documento cerrado antes de usar la transmisión. – Toft

+0

¿Cómo abriría el pdf en lugar de guardarlo en el escritorio en su ejemplo? – Standage

0

Mientras que las costuras del PdfReader no pueden tomar la corriente, la matriz de la secuencia funciona.

var readerFrontPage = new PdfReader (streamFrontPage.ToArray());