Pregunta

Tengo un problema con la conversión al código de Excel que estoy encontrando. Estoy trabajando en un proyecto de sitio web en .NET 4.0, y he creado una clase para esto que hace lo siguiente (basado en http://mattberseth.com/blog/2007/04/export_gridview_to_excel_1.html ):

HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition",
string.Format("attachment; filename={0}", fileName)); HttpContext.Current.Response.ContentType = "application/ms-excel"; using (StringWriter sw = new StringWriter()) {
   using (HtmlTextWriter htw = new HtmlTextWriter(sw)) {
    //Create a table to contain the grid
    //Add header row
    //Add each data row
    //Add Footer row
    //Render the table into the htmlwriter
    //  render the htmlwriter into the response
    HttpContext.Current.Response.Write(sw.ToString());
    HttpContext.Current.Response.End();
  }
}

Llamo a esta clase desde un control de usuario que contiene un botón que se agrega a un GridView que se muestra en la página. Esto funciona como se esperaba: haga clic en el botón, se le presentará una opción de descarga para abrir o guardar la hoja de cálculo de Excel resultante que contiene los datos de GridView.

Sin embargo, cuando llamo a esto desde un botón de enlace dentro de un GridView diferente, me gustaría construir una vista de cuadrícula dinámica para contener datos y exportarlos. Cuando hago eso, obtengo una ThreadAbortException de la llamada Response.End en la clase.

Pregunta 1: ¿Por qué no obtengo esa excepción ThreadAbortException cuando llamo al mismo código desde un control de usuario? ¿Los controles de usuario obtienen sus propios hilos o algún otro tipo de contexto?

La búsqueda del error que obtengo cuando se produce la excepción ThreadAbortException me llevó a intentar reemplazarla con ApplicationInstance.CompleteRequest (). Cuando hago eso, ya no obtengo la ThreadAbortException, pero esto rompe el control de usuario que funcionaba anteriormente; en lugar de la hoja de cálculo de Excel resultante que contiene los datos de la cuadrícula, contiene el HTML de la página que lo contiene y, en cualquier caso, es bastante fácil de suprimir ese error con una captura vacía. Sin embargo, no corrige la llamada directa con GridView generado dinámicamente, ese código genera un error de JavaScript: "El mensaje recibido del servidor no se pudo analizar".

Me encantaría saber qué está pasando aquí exactamente, pero estoy en el punto de necesitar resultados independientemente de la comprensión. Todos los demás enfoques que he probado (cuadrícula de datos en lugar de GridView, etc.) tienen los mismos problemas y son esencialmente los mismos cuando se trata de "hacerse cargo" la respuesta actual y el uso de stringwriter y htmlwriter para convertir los datos en una respuesta con excel contentType. Y dado que esto funciona de manera demostrable en el contexto de un control de usuario, estoy al final de mi ingenio en cuanto a por qué no funcionará cuando se llame directamente ...

¿Fue útil?

Solución 3

En realidad, el problema no tenía nada que ver con la exportación de Excel.El error "... no se pudo analizar" fue la clave.De estos enlaces obtuve la clave, que era que los eventos de la cuadrícula solo causan un evento de devolución de datos parcial:

http://forums.asp.net/t/1392827.aspx

http://forums.aspfree.com/net-development-11/gridview-footer-template-button-in-updatepanel-not-posting-back-236087.html

Esto explica la excepción ThreadAbortException y el error "... no se pudo analizar".Agregar esto al OnPreRender del ImageButton fue la solución:

protected void addTrigger_PreRender(object sender, EventArgs e)
{
    if (sender is ImageButton)
    {
        ImageButton imgBtn = (ImageButton)sender;
        ScriptManager ScriptMgr = (ScriptManager)this.FindControl("ScriptManager1");
        ScriptMgr.RegisterPostBackControl(ImgBtn);
    }
}

Otros consejos

Prueba en su lugar: HttpApplication.CompleteRequest () según: http://www.c6software.com/codesolutions/dotnet/threadabortexception.aspx

Hablan del html adicional que se muestra

usa esto

   Response.Clear()
    Response.AddHeader("content-disposition", atchment;filename=fm_specification.xls")
    Response.Charset = ""
    Response.Cache.SetCacheability(HttpCacheability.NoCache)
    Response.ContentType = "application/vnd.xls"
    Dim stringWrite As System.IO.StringWriter = New System.IO.StringWriter
    Dim htmlwrite As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite)
    GridView1.RenderControl(htmlwrite)
    Response.Write(stringWrite.ToString)
    Response.End()

en lugar de gridview1 puede usar div

                            dont forget to add this on your page

 Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
 End Sub

El evento en el que se llama al código Export to Excel, debe realizar una devolución de datos completa.el problema se debe a que solo realiza una devolución de datos parcial.

Tuve el mismo error y se resolvió cuando hice una devolución de datos completa.

Espero que esto ayude a alguien.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top