2012-09-24 32 views
5

Estoy usando iTextSharp 5.3.2.0 para agregar información a un archivo PDF existente que contiene un W-2 formar. Todo está funcionando perfectamente y el archivo PDF se ve muy bien cuando se escribe en la secuencia de respuesta del navegador; sin embargo, cuando el usuario termina de mirar el PDF, se le pregunta "¿Desea guardar los cambios en 'W2.pdf' antes de cerrar?" cada vez que ve el documento desde la página web.Usar iTextSharp para escribir datos en PDF funciona muy bien, pero Acrobat Reader pregunta '¿Desea guardar cambios?' Al cerrar el archivo

Al tratar de reducir el problema, en realidad he eliminado todas mis modificaciones, pero el problema continúa. Aquí está la versión simple de mi código, con mi llamada de escritura de datos comentada:

PdfReader pdfReader = new PdfReader(dataSource.ReportTemplate); 

using(MemoryStream outputStream = new MemoryStream()) 
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream)) 
{ 
    //dataSource.DrawDataFields(pdfStamper); 
    pdfStamper.FormFlattening = true; 
    return outputStream; 
} 

En este caso, el PDF "vacío" se escribe en el navegador y se ve bien, pero todavía me preguntó: "¿ quieres guardar "cuando cierro la ventana de Acrobat.

En este momento estaba pensando que había algo mal con el archivo PDF de origen. Sin embargo, cuando devuelvo los bytes brutos del archivo PDF al navegador, NO me preguntan la pregunta "¿Quieres guardar?" Cuando utilizas el siguiente código.

byte[] bytes = File.ReadAllBytes(dataSource.ReportTemplate); 

using (MemoryStream outputStream = new MemoryStream()) 
{ 
    outputStream.Write(bytes, 0, bytes.Length); 
    return outputStream; 
} 

Mi conclusión es que iTextSharp está haciendo algo "malo" para el PDF en el proceso de apertura y escribir los bytes de la corriente, pero soy nuevo en iTextSharp y fácilmente podría ser falta algo.

FWIW, esto es Acobat Reader 10.1.4 de lo que estamos hablando.

EDITAR: El PDF original utilizado como plantilla es de aproximadamente 80K de tamaño. Si miro el archivo temporal que se transmite por mi navegador, el archivo PDF escrito por iTextSharp es de aproximadamente 150K. Sin embargo, cuando respondo "Sí" a la pregunta "Guardar cambios" formulada por Acrobat Reader, el archivo resultante es aproximadamente 80K nuevamente. iTextSharp definitivamente está haciendo algo inesperado en este archivo.

+0

posible duplicado: http://stackoverflow.com/questions/2186817/itextsharp-filestream-corrupt-pdf-file – VahidN

+0

Sin duda, un duplicado con http://thread.gmane.org/gmane.comp.java.lib. itext.general/63197 –

+0

IMO, este es un problema diferente al relacionado por VahidN: observe que estoy leyendo en un archivo PDF existente, y luego escribiendo texto sobre él. Pero incluso si comento mi código de escritura de texto, el problema ocurre. – marc

Respuesta

14

no de trabajo:

public byte[] MergeDataByDrawing(int copies) 
{ 
    PdfReader pdfReader = new PdfReader(reportTemplate); 

    using (MemoryStream outputStream = new MemoryStream()) 
    using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream)) 
    { 
     pdfStamper.FormFlattening = true; 
     return outputStream.GetBuffer(); 
    } 
} 

de Trabajo:

public byte[] MergeDataByDrawing(int copies) 
{ 
    PdfReader pdfReader = new PdfReader(reportTemplate); 

    using (MemoryStream outputStream = new MemoryStream()) 
    using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream)) 
    { 
     pdfStamper.FormFlattening = true; 
     return outputStream.ToArray(); 
    } 
} 

Parece que el método GetBuffer es un problema. No entiendo por qué, pero tomaré el resultado.

Props to MKL for giving me an idea y Fredrik for the right example at the right time.

+2

'MemoryStream.GetBuffer()' puede agregar basura a los datos reales contenidos en la secuencia. [Consulte la documentación] (http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer.aspx). Por lo tanto, cuando trabaje con iTextSharp, siempre llame a 'ToArray()' en su lugar. – kuujinbo

+2

Un PDF se lee de abajo hacia arriba. Un lector de PDF espera que los bytes finales sean '%% EOF'. Si se agregan otros bytes después de la aparición final de '%% EOF', algunos lectores intentarán solucionarlo. ¿'ToArray()' soluciona su problema? En ese caso, no es necesario enviarme el PDF. Para asegurarse de que tiene la solución correcta, puede comparar el número de bytes producidos por 'GetBuffer()' vs 'ToArray()'. Si 'ToArray()' genera menos bytes, ha resuelto el problema. –

+0

Sí, ToArray() casi redujo a la mitad el número de bytes que se devolvieron y ¡listo !, todo estaba bien. – marc

1

Ver http://itextpdf.com/history/?branch=52&node=521

Bugfix AcroForms: En algunos casos, Adobe Reader X le pregunta si desea "guardar cambios" después de cerrar un formulario PDF aplanada. Esto se debió a la presencia de de algunas entradas innecesarias en el diccionario/AcroForm (para la instancia añadida cuando el formulario se creó con OOo).

Soy Bruno quien solucionó el error. Recuerdo que ocurrió en Adobe Reader 10, pero no en Adobe Reader 9. Pude solucionar el error porque la persona que lo informó fue un cliente que me envió un PDF que mostraba este comportamiento.

Si compartiera su PDF, podríamos echar un vistazo y ver qué otras entradas deberían eliminarse del diccionario /AcroForm. Solo eliminé aquellos que se agregaron cuando se creó el formulario usando Open Office. Si no quiere compartir el PDF, la causa siempre será un misterio.

+0

Estoy ansioso por compartir mi PDF, ¿cómo puedo obtenerlo? Diré que traté de hacer un "pdfReader.Catalog.Remove (PdfName.ACROFORM)", pero eso no tuvo ningún efecto. – marc

Cuestiones relacionadas