这是我在这个论坛上的第一个问题,请原谅任何新手错误。
我在Web应用程序中有.Net代码,它根据从数据库中提取的数据动态创建html表,然后将其流式传输到用户的Web浏览器以在Excel中打开。这在Chrome中运行得很好。它也适用于IE 11,只要用户点击“下载”链接后,选择“保存”选项(在打开文件之前保存文件),而不是“打开”选项 - 试图读取文件是流向客户端。但是在IE 11中,如果他们选择“打开”选项,他们会收到来自Excel的关于文件格式的警告(因为它是一个html文件 - 如果他们先保存就会发生同样的事情,这是可以接受的),但是当他们点击“是”打开时,他们会看到“无法读取文件”。错误信息。
在一个案例中,我能够通过替换“&”的实例来解决这个问题。在数据中加上“和”。但是,在其他情况下,我无法确定导致问题的特定数据值。而且,只要用户首先保存文件,文件就会打开。 (事实上,当我在开发环境中单击“打开”而不是“保存”时,它甚至可以正常工作 - 但是当我从部署代码的测试服务器上执行此操作时却不行。)
所以,我正在寻找一种方法来删除/替换html表的“td”元素中显示的所有有问题的数据,或者更好的是,某种方式只是使“打开”选项具有相同的结果作为“保存”选项。同样,只要首先保存文件,html表内容就会打开。
html表由C#类生成,但流式传输文件的页面在VB.Net中。我不认为C#代码会有用(但我可以将其部分发布,如果有人认为的那样),但这里是相关部分的VB代码:
Response.Clear()
Response.ClearContent()
Response.ClearHeaders()
Dim htmlTable As String
'[snip - populate htmlTable with data from database]
Dim fileName As String = "Whatever.xls"
Response.Buffer = false
Response.ContentType = "application/vnd.ms-excel"
Response.AppendHeader("Content-Disposition", "attachment; filename=""" & fileName & """")
Response.AddHeader("Content-Length", ASCIIEncoding.ASCII.GetByteCount(htmlTable).ToString())
Using ms As New MemoryStream(Encoding.ASCII.GetBytes(htmlTable))
ms.WriteTo(Response.OutputStream)
Response.Flush()
End Using
更新:我可能通过使用下面的(C#)代码“清理”数据来解决这个问题,但我仍然不明白为什么必须首先保存文件,这会使这不必要。任何答案都会受到欢迎。
private string GetDataRow(DataRow dr, List<DataColumnInfo> fieldInfoList)
{
var sb = new StringBuilder("<tr valign='top' align='left'>");
// see http://stackoverflow.com/questions/4619909/format-html-table-cell-so-that-excel-formats-as-text
var forceExcelText = "mso-number-format:\"\\@'\"";
fieldInfoList.ForEach(c =>
{
var content = dr[c.FieldName].ToString()
.Replace("&", "and")
.Replace("<", "")
.Replace(">", "");
// replace all non-asccii
content = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(dr[c.FieldName].ToString()));
sb.Append("<td style='" + forceExcelText + "'>" + content + "</td>");
});
sb.Append("</tr>");
return sb.ToString();
}
NEW UPDATE - 上面的代码没有解决问题。在某些情况下,选择“打开”选项而不是先“保存”时仍会出现错误。如果我先保存,一切都很好。
答案 0 :(得分:1)
我遇到同样的问题,从下面的行中删除“.vnd”开始为我工作。
Response.ContentType = "application/ms-excel"