API C# экспортирует Excel (ClosedXML) и загружает в Angular 6

Я сделал сообщение из Angular в C# Api с успешной передачей и смонтировал Excel с (ClosedXML).

Я могу отформатировать и сохранить в папке мой готовый файл Excel по своему желанию. Но мне нужно вернуть этот Excel в Angular в виде двоичного файла или аналогичного события загрузки в кнопку Angular 6 на странице.

Я знаю, что ошибка была в последних строках кода, потому что у меня есть, и я могу сохранить свой файл Excel локально, если я хочу,

Конец метода API C#:

[HttpPost]
        [Route("api/qqq/generateExcel")]
        public Task<HttpResponseMessage> Post(List<MyObject> list)
        {
        ...
var localWb = new XLWorkbook();

            localWb = arquivo.GerarExcel(listaRegras); 

            //----------------------
            var filePath = "C:\\Users\\folder";
            var fileName = "Export.xlsx"; 

            using (MemoryStream ms = new MemoryStream())
            {
                localWb.SaveAs(ms);
                using (FileStream file = new FileStream(filePath + "\\Export.xlsx", FileMode.Open, FileAccess.Read))
                {
                    HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
                    httpResponseMessage.Content = new ByteArrayContent(ms.GetBuffer());
                    httpResponseMessage.Content.Headers.Add("x-filename", fileName);
                    httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                    httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                    httpResponseMessage.Content.Headers.ContentDisposition.FileName = fileName;
                    httpResponseMessage.Content.Headers.ContentLength = file.Length;
                    httpResponseMessage.StatusCode = HttpStatusCode.OK;
                   // return httpResponseMessage;
                    return CreateResponse(HttpStatusCode.OK, httpResponseMessage);
                }    
            }

Мой угловой сервис:

gerarExcel(listaXYZ) {
    return this.http.post(this.apiUrl, listaXYZ);
  }

** составная часть**

exportToExcel(event): void {

    let lista= this.regras;
    let configs = '{ "config1": "valorConfig1", "config2": "valorConfig2" }';
    console.log(listaXYZ);
    //console.log(lista.length);

    if (lista != null) {
      this.myservice
        .gerarExcel(listaXYZ)
        .subscribe(data => {

          this.downloadFile(data)
          console.log(<any>data);

        },
          (error: HttpErrorResponse) => {
           ...
          },
          () => {
            ...
          }
        );
    }
    else {
      ...
    }


downloadFile(data: IDownloadArquivo) {
  var url = window.URL.createObjectURL(data.blob);

  let a = document.createElement("a");
  document.body.appendChild(a);

  a.style.display = "none";
  a.href = url;
  a.target = "_blank";
  a.download = data.fileName;
  a.click();

  a.remove();
}

Как я могу это сделать, ничего не происходит???

1 ответ

Решение

После многих исследований и без ответов я нашел решение. Я изменяю CloseXML на OfficeOpenXml, потому что последний может быть легко вставлен в содержимое Response с помощью Content = new ByteArrayContent (p) (см. Выше в разделе "Метод API").

Это было замечательно, потому что OfficeOpenXml может сделать стильную книгу по вашему желанию!!!

Конец метода API C#: Возвращение должно быть общедоступным HttpResponseMessage (без TASK)

public HttpResponseMessage GenerateMyExcel(List<someModel> mylist)
{
...
return httpResponseMessage;
...}

Exemple:

     [HttpPost]
            [Route("api/someModel/generateMyExcel")]
             public HttpResponseMessage GenerateMyExcel(List<someModel> mylist)
            { 
                var listSomeModelJson  = JsonConvert.SerializeObject(mylist);

var MyExcelObjectToMakeAWorkbook = new MyExcelObjectToMakeAWorkbook();

                using (var package = MyExcelObjectToMakeAWorkbook .GenerateAnWorkbook(mylist)
                {
                    var p = package.GetAsByteArray();

                    HttpResponseMessage httpResponseMessage = new HttpResponseMessage();

                    httpResponseMessage = new HttpResponseMessage
                    {
                        StatusCode = HttpStatusCode.OK,
                        Content = new ByteArrayContent(p)
                    };
                    httpResponseMessage.Content.Headers.Add("x-filename", "name.xlsx");
                    //.XLSX
                    httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                    httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                    httpResponseMessage.Content.Headers.ContentDisposition.FileName = "nome.xlsx";
                    httpResponseMessage.Content.Headers.ContentLength = p.Length;
                    httpResponseMessage.StatusCode = HttpStatusCode.OK;
                    return httpResponseMessage;
                }
            }

Компонент

...

    this.myModelService
          .generateExcelByPost(this.MyObjectList)
          .subscribe(
            (data) => {
              var file = new Blob([data], { type: 'application/vnd.ms-excel' });
              var fileURL = URL.createObjectURL(file);
              let a = document.createElement("a");
              document.body.appendChild(a);
              a.style.display = "none";
              a.href = fileURL;
              a.target = "_blank";
              a.download = "ListOfSomeModel.xlsx";
              a.click();
              a.remove();
            }
          )
...

Сервис

generateExcelByPost(list: any) {
    let headers = new HttpHeaders();
    headers.set('Content-Type', 'application/json');
    return this.http.post(API_Url,list,
      {
        headers: headers,
        responseType: "arraybuffer"
      }
    )
  }
Другие вопросы по тегам