导出到 Excel - ThreadAbortException

发布于 2024-11-16 07:06:44 字数 1679 浏览 5 评论 0原文

我在转换为 Excel 代码时遇到问题。我正在 .NET 4.0 中开发一个网站项目,我为此创建了一个类,它执行以下操作(基于 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();
  }
}

我从一个用户控件调用此类,该控件包含一个添加到页面上显示的 GridView 的按钮。这按预期工作 - 单击按钮,您将看到一个下载选项,用于打开或保存包含 GridView 数据的结果 Excel 电子表格。

但是,当我从不同 GridView 内的链接按钮调用它时,我想构建一个动态 gridview 来包含数据并将其导出。当我这样做时,我从类中的 Response.End 调用中收到 ThreadAbortException。

问题 1:为什么从用户控件中调用相同的代码时没有得到 ThreadAbortException?用户控件是否有自己的线程或其他类型的上下文?

搜索 ThreadAbortException 发生时出现的错误导致我尝试将其替换为 ApplicationInstance.CompleteRequest()。当我这样做时,我不再得到 ThreadAbortException,但这会破坏之前工作的用户控件 - 而不是包含网格数据的结果 Excel 电子表格,它包含来自包含页面的 HTML,并且无论如何它很容易抑制带有空捕获的错误。但是,它并没有修复使用动态生成的 GridView 的直接调用,该代码会呈现 JavaScript 错误:“无法解析从服务器收到的消息。”

我很想了解这里到底发生了什么,但无论理解如何,我都需要结果。我尝试过的所有其他方法(datagrid 而不是 GridView 等)都会遇到相同的问题,并且在涉及“接管”时本质上是相同的 当前响应并使用 stringwriter 和 htmlwriter 将数据呈现为具有 excel contentType 的响应。由于这在用户控件的上下文中明显有效,我对为什么它在直接调用时不起作用......

I'm having a problem with the conversion to Excel code I'm finding. I am working on a website project in .NET 4.0, and I have created a class for this that does the following (based on
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();
  }
}

I call this class from a usercontrol that contains a button that is added to a GridView displayed on the page. This works as expected - click the button, you are presented with a download option to either open or save the resulting excel spreadsheet containing the data from the GridView.

However, when I call this from a linkbutton inside a different GridView, I'd like to build a dynamic gridview to contain data and export that. When I do that, I get a ThreadAbortException from the Response.End call in the class.

Question 1: Why do I not get that ThreadAbortException when calling the same code from within a usercontrol? Do usercontrols get their own threads or some other kind of context?

Searching on the error I get when that ThreadAbortException occurs led me to attempt to replace it with ApplicationInstance.CompleteRequest(). When I do that I no longer get the ThreadAbortException, but this breaks the previously working usercontrol - instead of the resulting excel spreadsheet containing the data from the grid, it contains the HTML from the containing page, and at any rate it's easy enough to suppress that error with an empty catch. However, it doesn't fix the direct call with the dynamically generated GridView, that code renders a javascript error: "The message received from the server could not be parsed."

I would love to understand what exactly is going on here, but I'm at the point of needing results regardless of understanding. All the other approaches I've tried (datagrid instead of GridView, etc) run into the same problems, and are essentially the same when it comes down to "taking over"
the current response and using stringwriter and htmlwriter to render the data into a response with excel contentType. And since this demonstrably works in the context of a usercontrol, I am at my wit's end as to why it won't work when called directly...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

贵在坚持 2024-11-23 07:06:44

这个问题实际上与excel导出完全无关。 “……无法解析”错误是关键。从这些链接中我得到了关键,即网格事件仅导致部分回发事件:

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

这解释了ThreadAbortException 和“...无法解析”错误。将其添加到 ImageButton 的 OnPreRender 是解决方案:

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);
    }
}

The problem was actually completely unrelated to the excel export. The “…could not be parsed” error was the key. From these links I got the key, which was that the grid events cause only a partial postback event:

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

This explains the ThreadAbortException and the “…could not be parsed” error. Adding this to the OnPreRender of the ImageButton was the solution:

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);
    }
}
书间行客 2024-11-23 07:06:44

尝试改为:
HttpApplication.CompleteRequest()
按照:
http://www.c6software.com/codesolutions/dotnet/threadabortexception.aspx

他们讨论了正在刷新的附加 html

Try instead:
HttpApplication.CompleteRequest()
as per:
http://www.c6software.com/codesolutions/dotnet/threadabortexception.aspx

They discuss the additional html being flished

别念他 2024-11-23 07:06:44

使用这个

   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()

代替 gridview1 你可以使用 div

                            dont forget to add this on your page

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

use this

   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()

instead of gridview1 you can use div

                            dont forget to add this on your page

 Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
 End Sub
萌︼了一个春 2024-11-23 07:06:44

调用导出到 Excel 代码的事件必须进行完整回发。问题是因为它只进行部分回发。

我遇到了同样的错误,当我进行完整的回发时,它得到了解决。

希望这对某人有帮助。

The event on which the Export to excel code is called, must make a full postback. the issue is because it does only a partial postback.

I had the same error and it got solved when i did a full postback.

Hope this helps someone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文