Este articulo se desprende de uno anterior.
y por el pedido de CARLOS A. RESÉNDIZ MARTÍNEZ (que tiene su blog Raptor-NET) y sus recordatorios :)…
Nota: me estoy dando cuenta que tiene un enlace a mi blog así que voy a tener que hacer buena letra y lo invito a que siga posteando en su blog Raptor-NET
En el articulo anterior quise mostrar como exportar, aquí vamos a exportar mediante ExportToHTTPResponse y directamente en el objeto Response con un MemoryStream
Este articulo viene con ejemplo para la descarga al final.
Exportando dentro de un UpdatePanel
Cuando queremos exportar dentro de un UpdatePanel nos envía el siguiente mensaje por tratar de escribir en el Response, que escribe o intenta escribir fuera del contenedor del UpdatePanel
Mensaje:
Line: 4723
Error: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.
Details: Error parsing near ‘%PDF-1.2 %�� 1 0 ob’.
La imagen en mi IE8 de Windows 7:
Exportando
Ejemplo 1: con el metodo ExportToHTTPResponse
Aquí obtenemos el reporte y lo exportamos a la salida HTTP, sin necesidad de armar el content-type… damos el tipo de formato de exportación y listo. Como segundo parámetro recibe el objeto Response
protected void btnExportarPDF_Click(object sender, EventArgs e) { ReportDocument reporteDoc = ReporteCrear(); reporteDoc.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Response, true, "EjemploExportacion"); }
Ejemplo 2: armando la salida HTTP, utilizando ExportToStream
Aqui hacemos al viejo estilo de exportación, tomando el control del Reponse mediante un MemoryStream donde se encuentra el reporte
Con este MemoryStream también lo podemos enviar por email: String to Stream: para enviarlo como Attachment (tal vez otro post sobre un ejemplo de esto exclusivamente con Crystal Report)
El codigo para armar:
protected void btnExportarPDFv2_Click(object sender, EventArgs e) { //Cargar reporte. Enlazando a la fuente de datos. ReportDocument reporteDoc = ReporteCrear(); System.IO.Stream streamPDF; streamPDF = reporteDoc.ExportToStream(ExportFormatType.PortableDocFormat); System.IO.MemoryStream stream = (System.IO.MemoryStream)reporteDoc.ExportToStream(ExportFormatType.PortableDocFormat); Response.Buffer = false; Response.Clear(); Response.AddHeader("content-disposition", "attachment;filename=EjemploExportacion.pdf"); Response.ContentType = "application/pdf"; Response.BinaryWrite(stream.ToArray()); Response.End(); }
Pero en el UpdatePanel? No funciona. Hay que agregarlo a la coleccion de Triggers
Debemos agregar el botón en la colección de Triggers.
Esto lo debe hacer automáticamente el Update Panel lo de registrar cada control “interno” pero parece que hay un problema.
from MSDN:
“…Cuando la propiedad ChildrenAsTriggers de un control UpdatePanel se establece en true (valor predeterminado), los controles de devolución de datos que se encuentran dentro del control UpdatePanel se registran automáticamente como controles de devolución de datos asincrónica….”
Pero en este caso parecía que no :(, asi que hay que agregarlo a la colección de Triggers.
Así se puede exportar
Registrando el botón por código para actualizar asíncronamente? Tampoco me funciono
Tampoco me funciono registrar el control por codigo con el metodo ScriptManager.RegisterAsyncPostBackControl
En el ejemplo anterior para el botón btnExportarPDFv2 que esta dentro del UP
ScriptManager1.RegisterAsyncPostBackControl(btnExportarPDFv2);
NOTA: Si alguien me puede decir que pasa voy a agradecerlo!
Así que la única solución dentro de un Update Panel
Registrar el botón explícitamente (o sea mediante declaración) como Trigger.
Ejemplo para descargar
Si no puedes ver click aquí para la descarga
Enlaces
- Crystal Report:
- ScriptManager.RegisterAsyncPostBackControl
Registra un control como desencadenador de devoluciones de datos asincrónicas.
En varias ejemplos de la web he visto que se agregan las líneas
Response.Buffer = False
Response.ClearContent()
Response.ClearHeaders()
antes de la exportación. ¿Esto tiene algún beneficio, es necesario o simplemente sale sobrando?
@Alfredo
Si mal no recuerdo cuando realizas la exportación con el metodo ExportToHttpResponse hay una sobrecarga que envias el objeto Response..y creo que recordar que alli dentro limpia la respuesta.
O sea: No es necesario.
Pero hay que ver como estas exportando tu reporte.
Mas info:
http://geeks.ms/blogs/fernandezja/archive/2007/11/04/exportar-crystal-report-document-a-excel-pdf-word-richtext-o-html-desde-c-243-digo.aspx
protected void Page_Load(object sender, EventArgs e)
{ ScriptManager.GetCurrent(this).RegisterPostBackControl(btnImprimir);
}
assim funciona.
Gracias @Antonio por compartirlo
Favor sigo teniendo problemas, nadie puede ayudarme, los estare agradecido, no puedo visualizar el reporte en PDF con Update Panel, me sale el mismo mensaje que al inicio.
Gracias
Hola @Ricky, puedes descargar el ejemplo? allí esta implementando la exportación dentro de un UpdatePanel… dale una mirada
Cuando lo lanzas desde dentro de un Grid deberas hacerlo de la siguiente forma en el evento del boton:
protected void BTN_ExportarPDF_Load(object sender, EventArgs e)
{
ScriptManager1.RegisterPostBackControl((Control)sender);
}
Hola José
Muy bueno tu ejemplo y me saco dudas que tenia. Queria consultarte ya que tengo que mostrar un archivo pdf pero dentro de tab en un tabcontainer. Tu ejemplo se puede utilizar para mostrar este archivos pdf ???
Hola @Carlos
Mira si te sirve este articulo
– PDF Viewer Control Without Acrobat Reader Installed
http://www.codeproject.com/KB/applications/PDFViewerControl.aspx