c#通过WebAPI控制器发送Excel xls到js并将其保存为文件



我有一个收集数据的控制器,并且(仅用于测试目的)正确地将其保存为Excel文件,代码片段如下所示:

[HttpPost]
public async Task<FileContentResult> ExampleToExcel()
{
using (var workbook = new XLWorkbook())
{
IXLWorksheet worksheet = workbook.Worksheets.Add("Example sheet");
int index = 1;
foreach (ExampleItem tmp in exampleItems)
{
worksheet.Cell(index, 1).Value = tmp.SomeData;
index++;
}
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
string fileName = "TheName.xlsx");
using (var stream = new System.IO.MemoryStream())
{
workbook.SaveAs(stream);
var content = stream.ToArray();
var fileContentResult = new FileContentResult(content, contentType)
{
FileDownloadName = fileName
};
return await Task.FromResult(fileContentResult);
}
}
}

然后在*.js文件中得到

exampleExcelExport: function () {
httpClient.send({
url: "/Examples/ExampleToExcel",
method: 'POST'
}).done(function (response) {
var blob = response;
var binaryData = [];
binaryData.push(blob);
var a = document.createElement('a');
a.href = window.URL.createObjectURL(new Blob(binaryData, { type: "application/octet-stream" }))
a.download = response.FileDownloadName;
a.dispatchEvent(new MouseEvent('click'));
});
},

请注意在控制器端,Excel文件的长度约为30KB,在js端超过50KB,字节超过0x80的值编码为2字节。

字符串的差异*contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

类型:"应用程序/octet-stream" *

可能不是关于,反应比我想象的要大得多。即使它们与"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">保存的Excel文件仍然不正确,大小超过50KB,字节超过0x80编码两次。

请告诉我怎样才能做得正确?如何从响应中获得内容作为正确的字节数组并将其保存到文件,以及如何获得也在响应中因为响应的名称。FileDownloadNameisundefined?

看来你没有正确的头在你的api

您必须设置您的请求的Access-Control-Expose-Headers

一个最小的工作示例如下:

public ActionResult DownloadExcel() {
// do the stuff to get your byte array
var excelBytes = byte[];
// put in some headers so the file name is availble in the response
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return File(excelBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ,"filename_you_chose.xlsx")
}

在javascript端提取文件名:

function(response, status, xhr){
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=n]*=((['"]).*?2|[^;n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) { 
filename = matches[1].replace(/['"]/g, '');
}
}

}

最后从响应中提取内容

我已经找到解决办法了。基本上,它需要在c#中编码为Base64字符串,然后在js中解码。@Admin:主题可以关闭了!

最新更新