ASP.NET 下载导出 excel sheet 有时会呈现源页面本身

ASP.NET Downloading exported excel sheet sometimes renders the source page itselft

我有两个报告会在用户单击导出按钮时下载 excel 文件。它们都在外部库中使用相同的方法(如下所示)。其中一份报告使用生成的数据正常打开 excel sheet,而另一份报告显示 excel sheet 中的源页面设计。这发生在 VS2008 中。 这是怎么回事,如何解决?

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ClearContent();
            HttpContext.Current.Response.ClearHeaders();
            HttpContext.Current.Response.Buffer = true;
            HttpContext.Current.Response.ContentType = "application/ms-excel;";
            HttpContext.Current.Response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble());
            HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=Report.xls");
            HttpContext.Current.Response.Charset = "utf-8";
            HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;

            HttpContext.Current.Response.Write(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">");

            //sets font
            HttpContext.Current.Response.Write("<font style='font-size:10.0pt; font-family:Calibri;'>");

            if (addCurrentDate)
                HttpContext.Current.Response.Write("<h5 align='left'>" + DateTime.Now.ToString() + "</h5>");
            HttpContext.Current.Response.Write("<h2>" + title + "</h2>");

            string subttitlesString = string.Empty;
            if (subItems != null && subItems.Count > 0)
            {
                subttitlesString = "<table>";
                foreach (var item in subItems)
                {
                    subttitlesString += string.Format("<tr><td style='font-weight:bold;'>{0}</td><td>{1}</td></tr>", item.Key, item.Value);
                }
                subttitlesString += "</table>";
                HttpContext.Current.Response.Write(subttitlesString);
            }

            //sets the table border, cell spacing, border color, font of the text, background, foreground, font height
            HttpContext.Current.Response.Write("<Table border='1' bgColor='#ffffff' " +
              "borderColor='#000000' cellSpacing='0' cellPadding='0' " +
              "style='font-size:10.0pt; font-family:Calibri; background:white;'> <TR>");

            //am getting my grid's column headers
            int columnscount = table.Columns.Count;

            for (int j = 0; j < columnscount; j++)
            {      //write in new column
                HttpContext.Current.Response.Write("<Td>");
                //Get column headers  and make it as bold in excel columns
                HttpContext.Current.Response.Write("<B>");
                HttpContext.Current.Response.Write(table.Columns[j].ColumnName.ToString());
                HttpContext.Current.Response.Write("</B>");
                HttpContext.Current.Response.Write("</Td>");
            }

            HttpContext.Current.Response.Write("</TR>");
            foreach (DataRow row in table.Rows)
            {//write in new row
                HttpContext.Current.Response.Write("<TR>");
                for (int i = 0; i < table.Columns.Count; i++)
                {
                    HttpContext.Current.Response.Write("<Td>");
                    HttpContext.Current.Response.Write(row[i].ToString());
                    HttpContext.Current.Response.Write("</Td>");
                }

                HttpContext.Current.Response.Write("</TR>");
            }

            HttpContext.Current.Response.Write("</Table>");
            HttpContext.Current.Response.Write("</font>");
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();

这段代码被try-catch包围了吗?可能是渲染源页面的代码,你在某处遇到异常,这导致 HTML 的源页面被渲染。无论如何,你为什么要把 HTML 写成 application/ms-excel?

我找到了原因,现在很明显了。 上述导出方法的调用事件有两个catch段:

  1. ThreadAbortException
  2. 异常

ThreadAbortException 部分有 Thread.ResetAbort() 因为 ThreadAbortException 不断重新抛出自身。这似乎重置了之前添加的所有 HTTPRespnse 内容。