C# 无法从ASP.NET Web API后端生成并发送.xlsx文件到Vue.js前端

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: {

我正在尝试在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: {
    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();
})