导出的文件返回为 JSON 而不是 Excel 文件

Exported file is returning as JSON instead of Excel file

我正在尝试 return 一个 Excel 文件,但它总是试图保存 JSON 文件而不是 Excel 文件。你能告诉我这段代码有什么问题吗?我认为内容类型有误,但我在那里尝试了几个选项,但仍然 returning JSON...

/Excel 建设者

public class ExcelFileBuilder
{
    public byte[] BuildEmployeeRecordFile(IEnumerable<EmployeeRecordDto> records)
    {
        byte[] fileContents;
        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
        using (var package = new ExcelPackage())
        {
            var worksheet1 = package.Workbook.Worksheets.Add("TEST");
            //ADD data here

            // Export it to byte array
            fileContents = package.GetAsByteArray();
        }
        return fileContents;
}

/查询class

public class ExportEmployeeRecordQuery : IRequest<ExportEmployeeRecordVm>
{

}

public class ExportEmployeeRecordQueryHandler : IRequestHandler<ExportEmployeeRecordQuery, ExportEmployeeRecordVm>
{
    private readonly IApplicationDbContext _context;
    private readonly IExcelFileBuilder _fileBuilder;

    public ExportEmployeeRecordQueryHandler(IApplicationDbContext context, IExcelFileBuilder fileBuilder)
    {
        _context = context;
        _fileBuilder = fileBuilder;
    }

    public async Task<ExportEmployeeRecordVm> Handle(ExportEmployeeRecordQuery request, CancellationToken cancellationToken)
    {
        var vm = new ExportEmployeeRecordVm();
        
        //get data from db here
        vm.Content = _fileBuilder.BuildEmployeeRecordFile(null); //pass null for now
        vm.ContentType = "application/octet-stream";
        vm.FileName = "TestFile.xlsx";

        return await Task.FromResult(vm);
    }
}

/虚拟机

public class ExportEmployeeRecordVm
{
    public string FileName { get; set; }

    public string ContentType { get; set; }

    public byte[] Content { get; set; }
}

/Azure 函数

public class ExportAgentEmployeeRecordFunction
{
    private readonly IMediator _mediator;
    private readonly IHttpFunctionExecutor _httpFunctionExecutor;

    public ExportAgentEmployeeRecordFunction(IMediator mediator, IHttpFunctionExecutor httpFunctionExecutor)
    {
        _mediator = mediator;
        _httpFunctionExecutor = httpFunctionExecutor;
    }

    [FunctionName("ExportAgentEmployeeRecordFunction")]
    public async Task<IActionResult> Run(
       [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]
        ExportEmployeeRecordQuery qry)
    {
        return await _httpFunctionExecutor.ExecuteAsync(async () =>
        {
            var res = await _mediator.Send(qry);
            return new OkObjectResult(res);
        });
    }
}

我正在尝试 return 一个 Excel 文件,但它总是试图保存 JSON 文件而不是 Excel 文件。你能告诉我这段代码有什么问题吗?我认为内容类型有误,但我在那里尝试了几个选项,但仍然 returning JSON.

您使用了错误的派生操作结果类型

OkObjectResult

An ObjectResult that when executed performs content negotiation, formats the entity body, and will produce a Status200OK response if negotiation and formatting succeed

这意味着它正在包装传递的视图模型并根据请求将其作为 JSON 返回。

考虑到您要实现的目标,您需要使用 FileContentResult Class

Represents an ActionResult that when executed will write a binary file to the response.

并使用返回的视图模型的成员填充它

例如

//...

[FunctionName("ExportAgentEmployeeRecordFunction")]
public async Task<IActionResult> Run(
   [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]
    ExportEmployeeRecordQuery qry) {
    return await _httpFunctionExecutor.ExecuteAsync(async () => {
        ExportEmployeeRecordVm response = await _mediator.Send(qry);
        FileContentResult result =  new FileContentResult(response.Content, response.ContentType){
            FileDownloadName = response.FileName
        };
        return result;
    });
}

//...

您可以使用 OfficeOpenXml 库导出到 excel 文件。 示例代码:


  

     var data = YourDataSource ;
      ExcelPackage excel = new ExcelPackage();
     var workSheet = excel.Workbook.Worksheets.Add("Sheet1");
       workSheet.Cells[1, 1].LoadFromCollection(data, true);
      using (var memoryStream = new MemoryStream())
        {
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";  
      Response.AddHeader("content-disposition", $"attachment;  filename=myfile.xlsx");
       excel.SaveAs(memoryStream);
      memoryStream.WriteTo(Response.OutputStream);
         Response.Flush();
    Response.End();
                        }


</pre>