I have an ASP.Net MVC application that exports data to an Excel workbook; an .xlsx file.
The workbook is generated correctly on the server and Excel is able to open and display the file if I open it from the output directory (i.e. d:\sites\app\content\exported_data\dataset_2021-12-12.xlsx). This file is 24k in size.
When the workbook is downloaded via HTTP (i.e. http://site.company.com/content/exported_data/dataset_2021-12-12.xlsx), it cannot be opened by Excel. Excel will tell you the file is damaged and if you try to repair the file, that process fails. The downloaded file is 40k.
Server: Windows Server 2016 Data Center (10.0.14393.4704); IIS 10.0.14393.0
Client: Windows 10 (10.0.19041.1052); Chrome 96.0.4664.45
Static content compression is turned off.
What am I missing here?
Update #1
Downloading a .TXT file works just fine.
Update #2
Corruption also fails under IE11 and Edge.
Update #3
Request headers:
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
Response headers
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
Update #4
Screen capture of Beyond Compare 4 diff between the downloaded version (40kb) on the left and the server file (24kb) on the right.
Update #5
I solved the problem, though not the way I wanted to. (I did it in code, not at the server level, I'll detail that )
@BruceZhang-MSFT suggested that I try a different server. Which gave a different result.
The server exhibiting the behavior returns "Microsoft Windows [Version 10.0.14393]" when running ver.exe from the command line.
On another server that doesn't corrupt the Excel files on download, running ver.exe from the command line returns "Microsoft Windows [Version 10.0.17763.2300]".
If I change the controller code and explicitly set the encoding, like below, the Excel files download correctly.
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;
}
}
How do I push this encoding into the OS and IIS? It seems pretty specific to this particular build of Windows Server that I'm stuff with.