从Postman打电话时无法下载Excel文件

时间:2018-06-11 15:02:30

标签: c# excel asp.net-core asp.net-core-webapi

我正在尝试使用Web API下载Excel文件,但我无法在邮递员中下载文件,因为我在浏览器中输入URL时能够下载Excel文件虽然在打开文件时我收到如下警告消息:

enter image description here

enter image description here

enter image description here

当我使用POSTMAN命中端点时,文件被破坏并显示垃圾字符。

代码:

protected virtual byte[] ExportToXlsx<T>(IEnumerable<T> itemsToExport)
        {
            using (var stream = new MemoryStream())
            {
                using (var xlPackage = new ExcelPackage())
                {
                    // get handles to the worksheets
                    var worksheet = xlPackage.Workbook.Worksheets.Add(typeof(T).Name);

                    //create Headers and format them 
                    var manager = new PropertyManager<T>(itemsToExport.First());
                    manager.WriteCaption(worksheet, SetCaptionStyle);

                    var row = 2;

                    foreach (var items in itemsToExport)
                    {
                        manager.CurrentObject = items;
                        manager.WriteToXlsx(worksheet, row++, false);
                    }

                    xlPackage.Save();
                }
                return stream.ToArray();
            }
        }



private readonly IServiceContext ctx;
public void Download(string guid)
{
   var bytes = ExportToXlsx(list);
   ctx.reqobj.HttpContext.Response.Headers.Add("Content-Disposition", "attachment; filename=\"demo.xlsx\"");
   ctx.reqobj.HttpContext.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
   ctx.reqobj.HttpContext.Response.Body.Write(bytes, 0, bytes.Length);
}

注意:我正在使用OfficeOpenXml创建Excel文件。

我将不胜感激。

更新 enter image description here

3 个答案:

答案 0 :(得分:2)

需要将流传递给包。

现在没有给包裹,

//...

using (var xlPackage = new ExcelPackage())

//...

因此没有任何内容保存到流中,这就是尝试打开文件时显示错误的原因。

无需将内存流转换为数组。返回流并将其传递给响应。

protected virtual Stream ExportToXlsx<T>(IEnumerable<T> itemsToExport) {
    var stream = new MemoryStream();
    using (var xlPackage = new ExcelPackage(stream)) { //<<< pass stream
        // get handles to the worksheets
        var worksheet = xlPackage.Workbook.Worksheets.Add(typeof(T).Name);
        //create Headers and format them 
        var manager = new PropertyManager<T>(itemsToExport.First());
        manager.WriteCaption(worksheet, SetCaptionStyle);
        var row = 2;
        foreach (var items in itemsToExport) {
            manager.CurrentObject = items;
            manager.WriteToXlsx(worksheet, row++, false);
        }
        xlPackage.Save();
    }
    return stream;
}

返回文件的控制器操作如下所示

public IActionResult Download(string guid) {

    //...get list

    var file = ExportToXlsx(list);
    var contentType = "application/vnd.openxmlformats";
    var fileName = "demo.xlsx";

    return File(file, contentType, fileName); //returns a FileStreamResult
}

评论中指出,上述内容是在支持方法中完成的。

使用相同的方法

private readonly IServiceContext ctx;

//...

public void Download(string guid) {

    //...get list

    using(var fileStream = ExportToXlsx(list)) {
        if (fileStream.CanSeek && fileStream.Position != 0) {
            fileStream.Seek(0, SeekOrigin.Begin);
        }
        var contentType = "application/vnd.openxmlformats";
        var fileName = "demo.xlsx";
        var response = ctx.reqobj.HttpContext.Response;
        response.Headers.Add("Content-Disposition", $"attachment; filename=\"{fileName}\"");
        response.Headers.Add("Content-Length", fileStream.Length.ToString());
        response.ContentType = contentType;
        fileStream.CopyTo(response.Body);
    }
}

将生成的文件复制到响应正文中。

至于邮差,该工具只是在响应中显示内容返回。它不会尝试将实际文件作为附件下载。

答案 1 :(得分:2)

Postman不会下载任何文件,只返回服务器或您的服务提供的数据。我有一个项目,下载一个excel与OpenXML这里是一个例子,你可以用一些样式来指导。

[HttpGet]
    public void DownloadTable(int id)
    {
        List<Employee> all = db.Employees.Where(x => x.ManagerId == id).ToList();
        String file = "Example.xlsx";
        String path = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data"), file);
        List<string[]> headerRow = new List<string[]>() { new string[] { "EmployeeId", "Name", "Shift", "Timestamp" } };
        string headerRange = "A2:" + Char.ConvertFromUtf32(headerRow[0].Length + 64) + "2";
        ExcelPackage excel = new ExcelPackage();
        excel.Workbook.Worksheets.Add("Employees");
        var page = excel.Workbook.Worksheets["Employees"];
        page.Cells["A1:D1"].Merge = true;
        page.Cells["A1:D1"].Value = "Supervisor: " + all.FirstOrDefault().Manager + " - " + id;
        page.Cells["A1:D1"].Style.Font.Bold = true;
        page.Cells[headerRange].LoadFromArrays(headerRow);

        int z = 3;
        foreach (Reporte r in all)
        {
            page.Cells["A" + z].Value = r.Id;
            page.Cells["B" + z].Value = r.Name;
            page.Cells["C" + z].Value = r.Shift;
            page.Cells["D" + z].Value = r.Timestamp;
            z++;
        }

        page.Cells["D3:D" + z].Style.Numberformat.Format = "dddd dd MMMM YYYY";
        page.Cells["A2:D2"].AutoFilter = true;

        page.Cells["A1:D" + z].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
        page.Cells["A1:D" + z].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
        page.Cells["A2:D" + z].AutoFitColumns();
        page.Cells["A1:D1"].Style.Fill.PatternType = ExcelFillStyle.Solid;
        page.Cells["A1:D1"].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(1, 183, 222, 232));
        FileInfo excelFile = new FileInfo(path);
        excel.SaveAs(excelFile);

        System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
        response.ClearContent();
        response.Clear();
        response.ContentType = "text/plain";
        response.AddHeader("Content-Disposition",
                           "attachment; filename=" + file + ";");
        response.TransmitFile(path);
        response.Flush();
        response.End();
        File.Delete(path);
    }

答案 2 :(得分:0)

尝试使用“发送和下载”代替“发送”

https://www.getpostman.com/docs/v6/postman/sending_api_requests/responses