C# 无法从ASP.NET Web API后端生成并发送.xlsx文件到Vue.js前端
我正在尝试在ASP.NET Web API后端生成一个excel文件,并将其发送到Vue.js前端进行下载 正在通过调用getQueryResults发出API请求:C# 无法从ASP.NET Web API后端生成并发送.xlsx文件到Vue.js前端,c#,vue.js,asp.net-web-api,axios,epplus-4,C#,Vue.js,Asp.net Web Api,Axios,Epplus 4,我正在尝试在ASP.NET Web API后端生成一个excel文件,并将其发送到Vue.js前端进行下载 正在通过调用getQueryResults发出API请求: const apiClient = axios.create({ baseURL: process.env.NODE_ENV == "production" ? PROD_URL : TEST_URL, withCredentials: true, // This is the default headers: {
const apiClient = axios.create({
baseURL: process.env.NODE_ENV == "production" ? PROD_URL : TEST_URL,
withCredentials: true, // This is the default
headers: {
Accept: "application/json",
"Content-Type": "application/json"
}
});
getQueryResults(table, filters, selected, clientId, fundId, periodId, pageNumber, pageSize, exportExcel){
return apiClient.post(`queryResults`, {
responseType: 'blob',
table,
filters,
selected,
clientId,
fundId,
periodId,
pageNumber,
pageSize,
exportExcel
});
}
在后端,excel文件在QueryResultsExport.cs的内部生成,EPPlus版本为4.1.0:
public static MemoryStream exportToExcel(IQueryable<object> itemsToExport)
{
if (itemsToExport.Count() == 0)
return null;
ExcelPackage excel = new ExcelPackage();
ExcelWorksheet workSheet = excel.Workbook.Worksheets.Add("Query Results");
DataTable dataTable = toDataTable(itemsToExport.ToList());
workSheet.Cells["A1"].LoadFromDataTable(dataTable, true);
/*
string path = @"C:\Users\asdfq321\Downloads\test11.xlsx";
Stream stream = File.Create(path);
excel.SaveAs(stream);
stream.Close();
return null;
*/
MemoryStream ms = new MemoryStream(excel.GetAsByteArray());
excel.Dispose();
return ms;
}
结果是出现一个弹出框,提示我下载excel文件。但是,无法读取该文件,当打开该文件时,会显示消息,我们发现asdfq.xlsx中的某些内容存在问题。你想让我们尽力恢复吗?如果您信任此工作簿的来源,请单击“是”。单击“是”时,由于文件格式或文件扩展名无效,Excel无法打开文件asdfq.xlsx。验证文件是否已损坏,以及文件扩展名是否与文件格式匹配
当我在browser dev tools Network选项卡中查看响应时,我看到响应的内容长度为:3442,这似乎是正确的:这与我先前成功保存在服务器上的excel文件相匹配。但是,最终下载的excel文件大小为5635字节
以下是响应标题的图片:
以下是Console.logresult的图片:
我尝试过各种各样的事情,比如更改responseType、传入blob构造函数的类型、请求中的header ContentType、Accept header、如何将内存流添加到响应中等等,但我一直没有成功:结果总是一样的;损坏的excel文件,大小为5635字节,而不是预期的3442字节。任何帮助都将不胜感激;谢谢
编辑:我注意到在我粘贴的代码片段中,我
httpResponseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
在后端,但在前端我有
var myBlob = new Blob([result.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})
我确实尝试将它们都设置为application/octet-stream,或者都设置为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,但这没有什么区别
我还尝试了不同的方法来产生响应:
//attempt 1
MemoryStream ms = QueryResultsExport.exportToExcel(queryItems);
HttpResponseMessage httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
httpResponseMessage.Content = new StreamContent(ms);
httpResponseMessage.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
httpResponseMessage.Content.Headers.ContentDisposition.FileName = "asdfq.xlsx";
httpResponseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
// ms.Close();
return httpResponseMessage;
//attempt 2
MemoryStream ms = QueryResultsExport.exportToExcel(queryItems);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(ms.ToArray())
};
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "asdfq.xlsx";
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
return result;
// atempt 3
MemoryStream ms = QueryResultsExport.exportToExcel(queryItems);
ms.Position = 0;
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(ms.GetBuffer())
};
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"){FileName = "export.xlsx"};
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
result.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
result.Content.Headers.Add("content-length", ms.Length.ToString());
return result;
最后,在QueryResultsExport.exportToExcel中,我也尝试了
var ms = new MemoryStream();
excel.SaveAs(ms);
return ms;
但所有这些都没有任何区别。我可以通过将excel文件作为StringContent而不是ByteArrayContent发送,使其正常工作,如下所示: 在api请求中分配responseType似乎没有必要。设置Content.Headers.ContentDisposition或Content.Headers.ContentType也不起作用
//attempt 1
MemoryStream ms = QueryResultsExport.exportToExcel(queryItems);
HttpResponseMessage httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
httpResponseMessage.Content = new StreamContent(ms);
httpResponseMessage.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
httpResponseMessage.Content.Headers.ContentDisposition.FileName = "asdfq.xlsx";
httpResponseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
// ms.Close();
return httpResponseMessage;
//attempt 2
MemoryStream ms = QueryResultsExport.exportToExcel(queryItems);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(ms.ToArray())
};
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "asdfq.xlsx";
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
return result;
// atempt 3
MemoryStream ms = QueryResultsExport.exportToExcel(queryItems);
ms.Position = 0;
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(ms.GetBuffer())
};
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"){FileName = "export.xlsx"};
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
result.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
result.Content.Headers.Add("content-length", ms.Length.ToString());
return result;
var ms = new MemoryStream();
excel.SaveAs(ms);
return ms;
MemoryStream ms = QueryResultsExport.exportToExcel(queryItems);
string base64String = System.Convert.ToBase64String(ms.ToArray(), 0, ms.ToArray().Length);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(base64String)
};
return result;
.then(result => {
const link = document.createElement('a');
link.href = 'data:application/octet-stream;charset=utf-8;base64,' + result.data;
link.target = '_blank';
link.download = 'asdfq.xlsx';
link.click();
})