从angular色js的web api下载csv文件

我的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; } 

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

 $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但没有文件types扩展名的文件。 该文件的内容是[Object object]

在IE10中,没有下载。

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

更新:这可能适用于你们那里的同样的问题: 链接

尝试像这样:

 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(); }); 

基于这个问题中最优秀的答案

我使用下面的解决scheme,它为我工作。

  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(); } 

Chrome 42中没有一款适合我

相反,我的指令现在使用这个linkfunction( 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(); }); } 

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

@斯科特的答案在这里为我工作:

使用AngularJS从ASP.NET Web API方法下载文件

我最近不得不实施这个。 想分享我所想的;

为了使它在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(); 

a.download不被IE支持。 至less在HTML5“支持”页面。 🙁

使用Ajax / XMLHttpRequest / $ http来调用WebApi方法,而不是使用html表单。 这样浏览器在响应头文件中使用文件名和内容types信息来保存文件,而且你不需要解决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> 

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

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

我认为下载任何由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")); });