Esporta in Excel: ThreadAbortException
-
29-10-2019 - |
Domanda
Ho un problema con la conversione in codice Excel che trovo. Sto lavorando a un progetto di sito web in .NET 4.0 e ho creato una classe per questo che fa quanto segue (basato su 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();
}
}
Chiamo questa classe da un usercontrol che contiene un pulsante che viene aggiunto a un GridView visualizzato nella pagina. Funziona come previsto: fai clic sul pulsante, ti viene presentata un'opzione di download per aprire o salvare il foglio di calcolo Excel risultante contenente i dati da GridView.
Tuttavia, quando lo chiamo da un pulsante di collegamento all'interno di un GridView diverso, mi piacerebbe creare un gridview dinamico per contenere i dati ed esportarli. Quando lo faccio, ottengo un'eccezione ThreadAbortException dalla chiamata Response.End nella classe.
Domanda 1: Perché non ottengo quell'eccezione ThreadAbortException quando chiamo lo stesso codice da un usercontrol? I controlli utente ottengono i propri thread o qualche altro tipo di contesto?
La ricerca dell'errore che ottengo quando si verifica tale ThreadAbortException mi ha portato a tentare di sostituirlo con ApplicationInstance.CompleteRequest (). Quando lo faccio non ottengo più ThreadAbortException, ma questo interrompe il controllo utente precedentemente funzionante - invece del foglio di calcolo Excel risultante contenente i dati dalla griglia, contiene l'HTML dalla pagina contenente, e in ogni caso è abbastanza facile da sopprimere quell'errore con una cattura vuota. Tuttavia, non risolve la chiamata diretta con GridView generato dinamicamente, il codice restituisce un errore javascript: "Impossibile analizzare il messaggio ricevuto dal server."
Mi piacerebbe capire cosa sta succedendo esattamente qui, ma sono sul punto di aver bisogno di risultati indipendentemente dalla comprensione. Tutti gli altri approcci che ho provato (datagrid invece di GridView, ecc.) Incontrano gli stessi problemi e sono essenzialmente gli stessi quando si tratta di "subentrare" la risposta corrente e utilizzando stringwriter e htmlwriter per eseguire il rendering dei dati in una risposta con excel contentType. E poiché questo funziona in modo dimostrabile nel contesto di un controllo utente, non so perché non funzionerà quando viene chiamato direttamente ...
Soluzione 3
Il problema in realtà era completamente estraneo all'esportazione di Excel.L'errore "... non può essere analizzato" era la chiave.Da questi collegamenti ho ottenuto la chiave, ovvero che gli eventi della griglia causano solo un evento di postback parziale:
http://forums.asp.net/t/1392827.aspx
Questo spiega l'eccezione ThreadAbortException e l'errore "... non può essere analizzato".L'aggiunta di questo a OnPreRender di ImageButton era la soluzione:
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);
}
}
Altri suggerimenti
Prova invece: HttpApplication.CompleteRequest () secondo: http://www.c6software.com/codesolutions/dotnet/threadabortexception.aspx
Discutono dell'html aggiuntivo in corso
usa questo
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()
invece di gridview1 puoi usare div
dont forget to add this on your page
Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
End Sub
L'evento su cui viene chiamato il codice Export to Excel, deve effettuare un postback completo.il problema è perché esegue solo un postback parziale.
Ho riscontrato lo stesso errore ed è stato risolto quando ho eseguito un postback completo.
Spero che questo aiuti qualcuno.