从 WebAPI ASPNetCore 返回 Excel 文件
Posted
技术标签:
【中文标题】从 WebAPI ASPNetCore 返回 Excel 文件【英文标题】:Return Excel File from WebAPI ASPNetCore 【发布时间】:2017-06-04 10:03:24 【问题描述】:我正在尝试创建 WebAPI,它将使用 ClosedXML 库返回 Excel 文件。
如果我返回 FileStreamResult,一切正常。但是,如果我将其更改为 HttpResponseMessage,正如这里所讨论的 Web API Return A File,我将无法下载文件或查看内容并获取 JSON 字符串。
我想知道如何从这个 HttpResponseMessage 中提取文件内容。
我在浏览器或 PostMan 工具中进行了测试,得到的只是 JSON 字符串:
"version":
"major": 1,
"minor": 1,
"build": -1,
"revision": -1,
"majorRevision": -1,
"minorRevision": -1
,
"content":
"headers": [
"key": "Content-Disposition",
"value": [
"attachment; filename=ERSheet.xlsx"
]
,
"key": "Content-Type",
"value": [
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
]
]
,
"statusCode": 200,
"reasonPhrase": "OK",
"headers": [],
"requestMessage": null,
"isSuccessStatusCode": true
我的代码如下:
[HttpGet("ERSheet2")]
public HttpResponseMessage ER_GenerateWBLWorksheet2()
MemoryStream stream = new MemoryStream();
var workbook = new XLWorkbook();
var SheetNames = new List<string>() "15-16", "16-17", "17-18", "18-19", "19-20" ;
foreach (var sheetname in SheetNames)
var worksheet = workbook.Worksheets.Add(sheetname);
worksheet.Cell("A1").Value = sheetname;
workbook.SaveAs(stream);
stream.Seek(0, SeekOrigin.Begin);
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(stream.ToArray());
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
result.Content.Headers.ContentDisposition.FileName = "ERSheet.xlsx";
return result;
更新
这与这个问题Download file with ClosedXML 不同,因为我提到我已经通过使用'FileStreamResult' 使它工作。我之所以问这个问题是因为这个评论“最好返回带有 StreamContent 的 HttpResponseMessage ”。在此线程Web API Return A File 中制作。因此,尝试在 .Net Core 中使用 HttpResponseMessage 并且不知道它不再支持 Darin 的答案。
【问题讨论】:
此 ResponseMessage 没有任何内容。我的意思是Excel文件的内容。还是我不对? 对不起,我很困惑。我的 ResponseMessage 不包含任何内容或 HttpResponseMessage 不能用于保存任何内容? Download file with ClosedXML的可能重复 首先,您的 JSON 字符串没有 Excel 文件的任何内容 【参考方案1】:在 .NET Core 上运行的 ASP.NET Web API 不再支持 HttpResponseMessage
。因此,基本上它会尝试序列化您要返回到 JSON 的该对象的实例(就好像它是您的简单视图模型一样)。您可以使用一些compatibility shim hacks
,但总的来说,我建议您使用更惯用的方法 - 从您的操作中返回一个IActionResult
实例:
[HttpGet("ERSheet2")]
public IActionResult ER_GenerateWBLWorksheet2()
using (MemoryStream stream = new MemoryStream())
var workbook = new XLWorkbook();
var SheetNames = new List<string>() "15-16", "16-17", "17-18", "18-19", "19-20" ;
foreach (var sheetname in SheetNames)
var worksheet = workbook.Worksheets.Add(sheetname);
worksheet.Cell("A1").Value = sheetname;
workbook.SaveAs(stream);
stream.Seek(0, SeekOrigin.Begin);
return this.File(
fileContents: stream.ToArray(),
contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
// By setting a file download name the framework will
// automatically add the attachment Content-Disposition header
fileDownloadName: "ERSheet.xlsx"
);
【讨论】:
对,应该是主要原因。我试图在另一个答案中将它返回到这一行的 HttpResponse 中。 “最好返回带有 StreamContent 的 HttpResponseMessage。”谢谢。 是的,但这个答案是关于在完整 .NET 框架上运行的 ASP.NET Web API,而不是针对 .NET Core。 您如何看出该问题与 .Net 核心还是标准 .Net 相关?我在页面上的任何地方都找不到这些主题标签。【参考方案2】:我相信你应该使用:
response.Content = new ByteArrayContent(stream.GetBuffer());
但是,我无法让它为 Angular2 工作。它确实适用于 Angular1。
【讨论】:
不清楚这个答案是如何相关的。这个问题没有提到使用 Angular。但也许你看到了我没有看到的东西,并且可以帮助提问者澄清问题?以上是关于从 WebAPI ASPNetCore 返回 Excel 文件的主要内容,如果未能解决你的问题,请参考以下文章
使用Swashbuckle.AspNetCore生成.NetCore WEBAPI的接口文档
将 httpHandler 附加到 httpclientFactory webapi aspnetcore 2.1
我可以在 AspNetCore WebAPI 中将 CancellationToken 作为参数传递吗
异常处理中间件不处理异常 - 调用 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware (ASP.NET Core WebAPI)