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段:
- ThreadAbortException
- 异常
ThreadAbortException 部分有 Thread.ResetAbort() 因为 ThreadAbortException 不断重新抛出自身。这似乎重置了之前添加的所有 HTTPRespnse 内容。
我有两个报告会在用户单击导出按钮时下载 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段:
- ThreadAbortException
- 异常
ThreadAbortException 部分有 Thread.ResetAbort() 因为 ThreadAbortException 不断重新抛出自身。这似乎重置了之前添加的所有 HTTPRespnse 内容。