Angular2 Загрузить файл Excel из Asp.Net Core Corrupted - PullRequest
0 голосов
/ 15 октября 2018

Так что я использую 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 КБ.

My Service:

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

}

My 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"

Файл загружается, однако в два раза больше оригинала, который я сохранил локально в моей системе при создании файла на контроллере.Я заметил, что размер, похоже, удвоился в функции getAsByteArray в ExcelPackage.сообщение, которое появляется при попытке открыть: «Мы обнаружили проблему с некоторым содержимым в« ..... xlsx ». Хотите восстановить?»в этот момент я нажимаю да и Excel зависает.Есть ли кто-нибудь, кто может указать мне правильное направление?

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Итак, теперь я понимаю, что проблема была на стороне моего контроллера:

Я пытался передать пакет 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");
    }
0 голосов
/ 15 октября 2018

Не думаю, что в параметрах запроса будет достаточно оставить простой элемент перечисления ResponseContentType.

Проверьте это:

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