从WebAPI ASPNetCore返回Excel文件

时间:2017-01-19 16:00:26

标签: asp.net-web-api asp.net-core

我正在尝试创建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不同,因为我提到我已经通过使用&#39; FileStreamResult&#39;来实现了它。我问这个因为这个评论&#34;最好用它内部的StreamContent返回HttpResponseMessage。&#34;在这个帖子Web API Return A File中制作。因此,尝试在.Net Core中使用HttpResponseMessage并且不知道它不再支持Darin的答案。

2 个答案:

答案 0 :(得分:5)

在.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"
        );
    }
}

答案 1 :(得分:0)

我相信你应该使用:

response.Content = new ByteArrayContent(stream.GetBuffer());

但是,我在为Angular2工作时遇到了问题。它可以与Angular1一起使用。