【问题标题】:download csv file from web api in angular js从 Angular js 中的 web api 下载 csv 文件
【发布时间】:2013-12-16 12:33:18
【问题描述】:

我的 API 控制器正在返回一个 csv 文件,如下所示:

    [HttpPost]
    public HttpResponseMessage GenerateCSV(FieldParameters fieldParams)
    {
        var output = new byte[] { };
        if (fieldParams!= null)
        {
            using (var stream = new MemoryStream())
            {
                this.SerializeSetting(fieldParams, stream);
                stream.Flush();
                output = stream.ToArray();
            }
        }
        var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(output) };
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "File.csv"
        };
        return result;
    }

我将发送和接收 csv 文件的 angularjs 如下所示:

$scope.save = function () {
            var csvInput= extractDetails();

            // File is an angular resource. We call its save method here which
            // accesses the api above which should return the content of csv
            File.save(csvInput, function (content) {
                var dataUrl = 'data:text/csv;utf-8,' + encodeURI(content);
                var hiddenElement = document.createElement('a');
                hiddenElement.setAttribute('href', dataUrl);
                hiddenElement.click();
            });
        };

在 chrome 中,它会下载一个名为 document 但没有文件类型扩展名的文件。 文件内容为[Object object]

在 IE10 中,没有下载任何内容。

我能做些什么来解决这个问题?

更新: 这可能对你们有同样问题的人有用:link

【问题讨论】:

  • DOM 操作不应该在控制器中完成

标签: javascript angularjs csv asp.net-web-api httpresponse


【解决方案1】:

试试看:

File.save(csvInput, function (content) {
    var hiddenElement = document.createElement('a');

    hiddenElement.href = 'data:attachment/csv,' + encodeURI(content);
    hiddenElement.target = '_blank';
    hiddenElement.download = 'myFile.csv';
    hiddenElement.click();
});

基于this question中最优秀的答案

【讨论】:

  • 那么 content 是一个对象,而不是一个 csv 字符串。 console.log content 看看你得到了什么。
  • 这是一个字符数组
  • 你能解决这个问题吗?我们也在 json 对象中获取 excel 文件的二进制内容。
  • 应该使用$http而不是$resource来获取csv字符串;预计 $resource 可以很好地处理 json 的对象
  • @Krishna 是正确的,请在此处查看类似的答案:stackoverflow.com/a/17888624/1848999
【解决方案2】:

我使用了以下解决方案,它对我有用。

 if (window.navigator.msSaveOrOpenBlob) {
   var blob = new Blob([decodeURIComponent(encodeURI(result.data))], {
     type: "text/csv;charset=utf-8;"
   });
   navigator.msSaveBlob(blob, 'filename.csv');
 } else {
   var a = document.createElement('a');
   a.href = 'data:attachment/csv;charset=utf-8,' + encodeURI(result.data);
   a.target = '_blank';
   a.download = 'filename.csv';
   document.body.appendChild(a);
   a.click();
 }

【讨论】:

    【解决方案3】:

    这些在 Chrome 42 中都不适合我...

    相反,我的指令现在使用这个 link 函数(base64 使它工作):

      link: function(scope, element, attrs) {
        var downloadFile = function downloadFile() {
          var filename = scope.getFilename();
          var link = angular.element('<a/>');
          link.attr({
            href: 'data:attachment/csv;base64,' + encodeURI($window.btoa(scope.csv)),
            target: '_blank',
            download: filename
          })[0].click();
          $timeout(function(){
            link.remove();
          }, 50);
        };
    
        element.bind('click', function(e) {
          scope.buildCSV().then(function(csv) {
            downloadFile();
          });
          scope.$apply();
        });
      }
    

    【讨论】:

    • 非常感谢为我节省了几个小时。
    • 这就是它的用途! :)
    【解决方案4】:

    最后一个答案为我工作了几个月,然后停止识别文件名,正如 adeneo 评论的那样......

    @Scott 的回答对我有用:

    Download file from an ASP.NET Web API method using AngularJS

    【讨论】:

      【解决方案5】:

      我最近不得不实施这个。想到分享我的发现;

      为了让它在 Safari 中工作,我必须设置目标:'_self',。不用担心 Safari 中的文件名。看起来不支持这里提到的; https://github.com/konklone/json/issues/56 (http://caniuse.com/#search=download)

      以下代码在 Mozilla、Chrome 和 Safari 中运行良好;

        var anchor = angular.element('<a/>');
        anchor.css({display: 'none'});
        angular.element(document.body).append(anchor);
        anchor.attr({
          href: 'data:attachment/csv;charset=utf-8,' + encodeURIComponent(data),
          target: '_self',
          download: 'data.csv'
        })[0].click();
        anchor.remove();
      

      【讨论】:

        【解决方案6】:

        与其使用 Ajax / XMLHttpRequest / $http 来调用您的 WebApi 方法,不如使用 html 表单。这样,浏览器使用响应标头中的文件名和内容类型信息保存文件,您无需解决 javascript 对文件处理的限制。您也可以使用 GET 方法而不是 POST,因为该方法返回数据。这是一个示例表单:

        <form name="export" action="/MyController/Export" method="get" novalidate>
            <input name="id" type="id" ng-model="id" placeholder="ID" />
            <input name="fileName" type="text" ng-model="filename" placeholder="file name" required />
            <span class="error" ng-show="export.fileName.$error.required">Filename is required!</span>
            <button type="submit" ng-disabled="export.$invalid">Export</button>
        </form>
        

        【讨论】:

          【解决方案7】:

          在 Angular 1.5 中,使用 $window 服务下载文件。

          angular.module('app.csv').factory('csvService', csvService);
          
          csvService.$inject = ['$window'];
          
          function csvService($window) {
              function downloadCSV(urlToCSV) {
                  $window.location = urlToCSV;
              }
          }
          

          【讨论】:

            【解决方案8】:

            IE 不支持 a.download。至少在 HTML5“支持”页面。 :(

            【讨论】:

              【解决方案9】:

              我认为下载 REST 调用生成的任何文件的最佳方法是使用 window.location 示例:

                  $http({
                      url: url,
                      method: 'GET'
                  })
                  .then(function scb(response) {
                      var dataResponse = response.data;
                      //if response.data for example is : localhost/export/data.csv
                      
                      //the following will download the file without changing the current page location
                      window.location = 'http://'+ response.data
                  }, function(response) {
                    showWarningNotification($filter('translate')("global.errorGetDataServer"));
                  });

              【讨论】:

                【解决方案10】:

                可行的解决方案:

                downloadCSV(data){   
                 const newBlob = new Blob([decodeURIComponent(encodeURI(data))], { type: 'text/csv;charset=utf-8;' });
                
                        // IE doesn't allow using a blob object directly as link href
                        // instead it is necessary to use msSaveOrOpenBlob
                        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
                          window.navigator.msSaveOrOpenBlob(newBlob);
                          return;
                        }
                
                        // For other browsers:
                        // Create a link pointing to the ObjectURL containing the blob.
                        const fileData = window.URL.createObjectURL(newBlob);
                
                        const link = document.createElement('a');
                        link.href = fileData;
                        link.download = `Usecase-Unprocessed.csv`;
                        // this is necessary as link.click() does not work on the latest firefox
                        link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
                
                        setTimeout(function () {
                          // For Firefox it is necessary to delay revoking the ObjectURL
                          window.URL.revokeObjectURL(fileData);
                          link.remove();
                        }, 5000);
                  }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-08-03
                  • 1970-01-01
                  • 2019-12-11
                  • 2013-12-14
                  • 2019-01-08
                  • 2019-05-20
                  相关资源
                  最近更新 更多