Angular2从Asp.Net Core下载Excel文件损坏

时间:2018-10-15 19:00:56

标签: excel angular http asp.net-core

因此,我将ASP.Net Core用作后端,将Angular用作前端。我正在尝试下载在控制器中创建的Excel文件:

  public IActionResult DownloadServerList()
    {
        byte[] fileContents;

        string fileName = @"servers.xlsx";

        if (System.IO.File.Exists(Path.Combine(@"C:\Users\EC64473\source\repos\ServerInventoryCore", fileName)))
            System.IO.File.Delete(Path.Combine(@"C:\Users\EC64473\source\repos\ServerInventoryCore", fileName));

        FileInfo file = new FileInfo(Path.Combine(@"C:\Users\EC64473\source\repos\ServerInventoryCore", fileName));

        using (ExcelPackage package = new ExcelPackage(file))
        {
            List<Server> serverList = context.Servers.ToList();

            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Servers");
            int totalRows = serverList.Count();

            worksheet.Cells[1, 1].Value = "Server ID";
            worksheet.Cells[1, 2].Value = "Server Name";
            worksheet.Cells[1, 3].Value = "Exists";
            worksheet.Cells[1, 4].Value = "UUID";
            int i = 0;
            for (int row = 2; row <= totalRows + 1; row++)
            {
                worksheet.Cells[row, 1].Value = serverList[i].ID;
                worksheet.Cells[row, 2].Value = serverList[i].ServerName;
                worksheet.Cells[row, 3].Value = serverList[i].ServerExists;
                worksheet.Cells[row, 4].Value = serverList[i].ServerUUID;
                i++;
            }
            package.Save();

            fileContents = package.GetAsByteArray();
        }

        //if (fileContents == null || fileContents.Length == 0)
        //    return NotFound();

        return File(
            fileContents: fileContents,
            contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            fileDownloadName: "servers.xlsx"
            );
    }

我可以确认将创建的Excel文件作为文件发送时未损坏,并且总大小为:约96 kb。

我的服务是:

 getServerListAsExcel(): Observable<any> {
return this.http.get('Servers/DownloadServerList', { responseType: ResponseContentType.Blob  });

}

我的Component.ts是:

 buttonPress() {
this.serverService.getServerListAsExcel()
  .subscribe(data => {
    console.log(data);
    saveAs(data._body, 'test.xlsx');
  });

记录数据时,结果为:

Response {_body: Blob(195104), status: 200, ok: true, statusText: "OK", 
headers: Headers, …}
headers: Headers
_headers: Map(8) {"date" => Array(1), "server" => Array(1), "x-powered-by" => 
Array(1), "content-type" => Array(1), "status" => Array(1), …}
_normalizedNames: Map(8) {"date" => "date", "server" => "server", "x-powered- 
by" => "x-powered-by", "content-type" => "content-type", "status" => "status", …}
__proto__: Object
ok: true
status: 200
statusText: "OK"
type: 2
url: "https://localhost:44312/Servers/DownloadServerList"
_body: Blob(195104)
size: 195104
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

文件下载,但是是我创建控制器文件时在系统上本地保存的原始文件大小的两倍。我注意到ExcelPackage的“ getAsByteArray”函数的大小似乎增加了一倍。尝试打开时出现的消息是“我们在'..... xlsx'中发现了某些内容问题。您要恢复吗?”这时我单击是,Excel挂起。有谁能指出我正确的方向?

2 个答案:

答案 0 :(得分:0)

我认为在请求选项中仅保留ResponseContentType枚举的普通项目是不够的。

检查:

getServerListAsExcel(): Observable<any> {
        return this.http.get('Servers/DownloadServerList', {responseType: ResponseContentType.Blob});
    }

答案 1 :(得分:0)

所以我现在意识到问题出在我的控制器端:

我试图将excel软件包作为字节数组传递,这应该没问题。 相反,我必须将其作为MemoryStream返回:

    public IActionResult DownloadServerList()
    {
        byte[] fileContents;

        string fileName = @"servers.xlsx";

        if (System.IO.File.Exists(Path.Combine(@"C:\Users\EC64473\source\repos\ServerInventoryCore", fileName)))
            System.IO.File.Delete(Path.Combine(@"C:\Users\EC64473\source\repos\ServerInventoryCore", fileName));

        FileInfo file = new FileInfo(Path.Combine(@"C:\Users\EC64473\source\repos\ServerInventoryCore", fileName));
        var stream = new MemoryStream();
        using (ExcelPackage package = new ExcelPackage(file))
        {
            List<Server> serverList = context.Servers.ToList();

            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Servers");
            int totalRows = serverList.Count();

            worksheet.Cells[1, 1].Value = "Server ID";
            worksheet.Cells[1, 2].Value = "Server Name";
            worksheet.Cells[1, 3].Value = "Exists";
            worksheet.Cells[1, 4].Value = "UUID";
            int i = 0;
            for (int row = 2; row <= totalRows + 1; row++)
            {
                worksheet.Cells[row, 1].Value = serverList[i].ID;
                worksheet.Cells[row, 2].Value = serverList[i].ServerName;
                worksheet.Cells[row, 3].Value = serverList[i].ServerExists;
                worksheet.Cells[row, 4].Value = serverList[i].ServerUUID;
                i++;
            }

            //package.Save();
            package.SaveAs(stream);
            stream.Position = 0;
            fileContents = package.GetAsByteArray();
        }

        if (fileContents == null || fileContents.Length == 0)
            return NotFound();

        return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "servers.xlsx");
    }