2010-05-19 34 views
5

Estoy usando itextsharp para completar mis archivos PDF. No tengo problemas con esto. Básicamente lo que estoy haciendo es obtener el PDF y llenar los campos en la memoria y luego devolver el MemoryStream para que se muestre en una página web. Todo esto funciona con un solo documento PDF.Rellenar varios archivos PDF

Lo que estoy tratando de averiguar ahora es fusionar varios archivos PDF en uno MemoryStream. La parte que no puedo descifrar es que los documentos que estoy poblando son idénticos. Entonces, por ejemplo, tengo un List<Person> que contiene 5 personas. Quiero completar un PDF para cada persona y fusionarlos todos en uno, en la memoria. Sin tener en cuenta, voy a completar el mismo tipo de documento para cada persona.

El problema que estoy recibiendo es que cuando trato de agregar una segunda copia del mismo PDF que se completará para la segunda iteración, simplemente sobrescribe el primer PDF rellenado, ya que es el mismo documento, por lo tanto, no agrega un segunda copia para el segundo Person en absoluto.

Así que, básicamente, si tuviera las 5 personas, terminaría con una sola página con los datos de la quinta persona, en lugar de un PDF con 5 páginas similares que contienen los datos de cada persona, respectivamente.

Aquí hay algo de código ...

MemoryStream ms = ms = new MemoryStream(); 
PdfReader docReader = null; 
PdfStamper Stamper = null; 
List<Person> persons = new List<Person>() { 
    new Person("Larry", "David"), 
    new Person("Dustin", "Byfuglien"), 
    new Person("Patrick", "Kane"), 
    new Person("Johnathan", "Toews"), 
    new Person("Marian", "Hossa") 
}; 

try 
{ 
    // Iterate thru all persons and populate a PDF for each 
    foreach(var person in persons){ 
     PdfCopyFields Copier = new PdfCopyFields(ms); 
     Copier.AddDocument(GetReader("Person.pdf")); 
     Copier.Close(); 

     docReader = new PdfReader(ms.ToArray()); 
     Stamper = new PdfStamper(docReader, ms); 
     AcroFields Fields = Stamper.AcroFields; 
     Fields.SetField("FirstName", person.FirstName); 
    } 
}catch(Exception e){ 
    // handle error 
}finally{ 
    if (Stamper != null) 
    { 
     Stamper.Close(); 
    } 
    if (docReader != null) 
    { 
     docReader.Close(); 
    } 
} 
+1

1 para Chicago Blackhawks !! :) –

+0

@ Cameron Peters: sí, son un equipo formidable. – Gabe

Respuesta

2

He creado una solución de trabajo, espero que esto ayude a alguien en el camino.

Crear un métodoPopulatePDF()que toma el objetoPersony devuelve unbyte[]:

private byte[] PopulatePersonPDF(Person obj) 
{ 
    MemoryStream ms = new MemoryStream(); 
    PdfStamper Stamper = null; 

    try 
    { 
     PdfCopyFields Copier = new PdfCopyFields(ms); 
     Copier.AddDocument(GetReader("Person.pdf")); 
     Copier.Close(); 

     PdfReader docReader = new PdfReader(ms.ToArray()); 
     ms = new MemoryStream(); 
     Stamper = new PdfStamper(docReader, ms); 
     AcroFields Fields = Stamper.AcroFields; 
     Fields.SetField("FirstName", obj.FirstName); 
    } 
    finally 
    { 
     if (Stamper != null) 
     { 
     Stamper.Close(); 
     } 
    } 
    return ms.ToArray(); 
} 

crear un métodoMergePDFs()que devuelve elMemoryStream:

private MemoryStream MergePDFs(List<byte[]> pdfs) 
{ 
    MemoryStream ms = new MemoryStream(); 
    PdfCopyFields Copier = new PdfCopyFields(ms); 

    foreach (var pdf in pdfs) 
     Copier.AddDocument(new PdfReader(pdf)); 
    Copier.Close(); 
    return ms; 
} 

Ejemplo de Aplicación:

List<Person> persons = new List<Person>() { 
    new Person("Larry", "David"), 
    new Person("Dustin", "Byfuglien"), 
    new Person("Patrick", "Kane"), 
    new Person("Johnathan", "Toews"), 
    new Person("Marian", "Hossa") 
}; 

List<byte[]> pdfs = new List<byte[]>(); 

foreach(var person in persons) 
    pdfs.Add(PopulatePersonPDF(person)); 

MemoryStream ms = MergePDFs(pdfs); 
+0

¿cómo se hace esto sin cargar la plantilla 10 veces? obtener 10x el tamaño –

+0

'PdfCopyFields' parece ser la inyección de dinero. Algo muy importante si está trabajando con transmisiones en la memoria: 'Copiadora PdfCopyFields = nueva PdfCopyFields (ms); Copier.Writer.CloseStream = false' –

0

Comprobar el constructor firma PdfStamper hay una sobrecarga que toma un valor booleano que indica que debe anexar al documento actual.