将文件从WebAPI下载到angular 6应用

时间:2019-01-29 12:22:51

标签: angular asp.net-web-api angular6

我使用带有.NET webApi(.NET 4.5框架)的角度为6的Web App。

我正在做的是收集一些用户输入,并将请求发送到webapi。 Webapi使用来自数据库的一些数据生成一个excel文件(xlsx或xlsm)。 现在,我需要在用户计算机上下载此文件。 我已在服务器上验证,生成的文件正确并在服务器上的temp目录中创建。 但是它正在作为损坏的文件下载到用户计算机上,而Excel无法打开它。

任何想法我该如何解决。

WebApi代码

[System.Web.Http.HttpPut]
        public ActionResult Put(Parameters inputs)
        {
            var path = GenerateFile(inputs);
            string extension = new FileInfo(path).Extension;
            switch (extension)
            {
               case ".xls":
                    return new FilePathResult(path, "application/msexcel");
                case ".xlsx":
                    return new FilePathResult(path, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                case ".xlsm":
                    return new FilePathResult(path, "application/vnd.ms-excel.sheet.macroEnabled.12");

            }
        }

角度代码:

GenerateReprot() {
    this.http.put(this.webApiURL, this.Input, 'arraybuffer')
      .subscribe(
        result => {
          this.downLoadFile(result, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
          alert('file downloaded successfully. ');
        },
        error => {
          alert('error with downloading file.');
        }
      );
  }

    downLoadFile(data: any, type: string) {
    var blob = new Blob([data], { type: type });
    var url = window.URL.createObjectURL(blob);

    var pwa = window.open(url);
    if (!pwa || pwa.closed || typeof pwa.closed == 'undefined') {
      alert('Please disable your Pop-up blocker and try again.');
    }
  }

3 个答案:

答案 0 :(得分:1)

您的标记显示,而您显示System.Web.Http名称空间,但是该框架没有使用ActionResult。所以看起来您正在混合MVC和Web API之间的框架

很可能您返回了错误的模型类型,并将其序列化为JSON,这就是文件读取器将其视为损坏的原因。

以下内容假设它是在ApiController

中调用的
[HttpPut]
public IHttpActionResult Put(Parameters inputs) {
    var path = GenerateFile(inputs);
    var file = new FileInfo(path);
    string contentType = null;
    switch (file.Extension) {
        case ".xls":
            contentType = "application/msexcel";
        case ".xlsx":
            contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        case ".xlsm":
            contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
    }

    var stream = file.OpenRead();

    var content = new StreamContent(stream);
    content.Headers.ContentLength = stream.Length; 
    content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
    content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
        FileName = file.Name
    };

    var response = Request.CreateResponse(HttpStatusCode.OK);
    response.Content = content;
    return ResponseMessage(response);
}

答案 1 :(得分:0)

在您的HTTP put请求中尝试responseType: "blob"

this.http.put(this.webApiURL, this.Input, { responseType: "blob" })
  .subscribe(
...
);

答案 2 :(得分:0)

Angular在下载文件时遇到一些奇怪的问题。仅发出put请求,我无法下载文件。我不得不将请求分为两部分 1.提出文件准备请求 2.收到文件下载请求

仅发出put请求,它总是下载1KB损坏的文件。 在Angular中,您也不需要使用任何arraybuffer或blob。它们还会引起一些奇怪的问题。

这是代码(webapi)

[HttpPut]
        public string Put(Parameters inputs)
        {
            var file = GenerateFile(inputs);
            return Path.GetFileNameWithoutExtension(file);
        }

        [HttpGet]
        public HttpResponseMessage Get(string id) //id is file name returned from above put request
        {
            var result = Request.CreateResponse(HttpStatusCode.OK);
            var fullPath = Path.Combine(Path.GetTempPath(), id + ".xlsx");

            if (!File.Exists(fullPath))
            {
                fullPath = Path.Combine(Path.GetTempPath(), id + ".xlsm");

                if (!File.Exists(fullPath))
                    throw new FileNotFoundException(id);
            }
            var stream = new MemoryStream(File.ReadAllBytes(fullPath));
            result.Content = new StreamContent(stream);

            switch (Path.GetExtension(fullPath))
            {
                case ".xls":
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/msexcel");
                    break;
                case ".xlsx":
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                    break;
                case ".xlsm":
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel.sheet.macroEnabled.12");
                    break;
            }

            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = Path.GetFileName(fullPath)
            };

            return result;
        }

角度代码:

GenerateReprot() {

    this.http.put(this.webApiURL, this.Input)
      .subscribe(
        result => {
          var url = this.webApiURL + result.json();
          window.open(url)

          alert('file downloaded successfully: ');

        }),
      error => {
        alert('error while downloading file');
      };
  }