我有一个 ASP.Net MVC 应用程序,它将数据导出到 Excel 工作簿; .xlsx 文件。
工作簿在服务器上正确生成,如果我从输出目录打开它(即 d:\sites\app\content\exported_data\dataset_2021-12-12.xlsx),Excel 能够打开并显示该文件。此文件大小为 24k。
当通过 HTTP 下载工作簿时(即http://site.company.com/content/exported_data/dataset_2021-12-12.xlsx),Excel 无法打开。Excel 会告诉您文件已损坏,如果您尝试修复该文件,该过程将失败。下载的文件为 40k。
服务器:Windows Server 2016 数据中心 (10.0.14393.4704);IIS 10.0.14393.0
客户端:Windows 10(10.0.19041.1052);Chrome 96.0.4664.45
静态内容压缩已关闭。
我在这里遗漏了什么?
更新 #1 下载.TXT 文件一切正常。
更新 #2 在 IE11 和 Edge 下损坏也会失败。
更新 #3 请求标头:
GET /content/exported_data/dataset_2021-12-12.xlsx HTTP/1.1
Host: site.company.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: _ga=GA1.2.22470475.1602604311; FWA Device Cookie=c44514ea-30ea-4579-969c-dfaad56002df; rxVisitor=1637946224265ID87N5ET43TH5SI86J0O7BJSLFDBSUIA; dtCookie=v_4_srv_2_sn_029F965CFA2AD25C362FEDB269BCC826_perc_100000_ol_0_mul_1_app-3Ae7bdf245ee5f8b62_1_app-3A65c25f0debc01cd8_1_rcs-3Acss_0; dtSa=-; dtLatC=26; FWA_Session_Cookie=b5427e92-983f-4b5d-82cc-83e2c2c468f7; ASP.NET_SessionId=zdpkziw4w1mtv3qt5bnj4tsi; dtPC=2$558067128_615h-vBVCARAAREUABLAKKHWMVOAUUMAHVUUGV-0e0; rxvt=1638821269230|1638819469230
If-None-Match: "55388354cfead71:0"
If-Modified-Since: Mon, 06 Dec 2021 18:30:22 GMT
响应标头
HTTP/1.1 304 Not Modified
Cache-Control: private
Accept-Ranges: bytes
ETag: "55388354cfead71:0"
Server: Microsoft-IIS/10.0
Set-Cookie: FWA Device Cookie=c44514ea-30ea-4579-969c-dfaad56002df; expires=Sun, 06-Mar-2022 19:45:26 GMT; path=/
Set-Cookie: FWA_Session_Cookie=b5427e92-983f-4b5d-82cc-83e2c2c468f7; expires=Mon, 06-Dec-2021 20:15:26 GMT; path=/
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Mon, 06 Dec 2021 19:45:26 GMT
更新 #4 左侧为下载版本(40kb)与右侧为服务器文件(24kb)之间 Beyond Compare 4 差异的屏幕截图。
更新 #5
我解决了这个问题,尽管不是我想要的方式。(我是在代码中完成的,而不是在服务器级别,我会详细说明)
@BruceZhang-MSFT 建议我尝试不同的服务器。结果却不同。
表现出该行为的服务器返回“Microsoft Windows [版本 10.0.14393]”从命令行运行 ver.exe 时。
在另一台未损坏下载的 Excel 文件的服务器上,从命令行运行 ver.exe 将返回“Microsoft Windows [版本 10.0.17763.2300]”。
如果我更改控制器代码并明确设置编码(如下所示),则 Excel 文件可以正确下载。
public FilePathResult XlsxDataTable(DataTable table, string reportName)
{
var rootName = reportName + "_" + DateTime.Now.ToString("yyyy-MM-dd_HH.mm.ss");
var fileName = rootName + ".xlsx";
var filePath = Path.Combine(Request.MapPath("~/Content/exported_data"), fileName);
using (XLWorkbook workbook = table.ToXlsx(rootName, filePath))
{
var result = new FilePathResult(filePath, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
result.FileDownloadName = fileName;
Response.ContentEncoding = Encoding.GetEncoding("ISO-8859-1"); // <-- This the new line that fixes the problem
return result;
}
}
如何将此编码推送到操作系统和 IIS?这似乎与我所熟悉的 Windows Server 特定版本非常相关。