从 Angular js 中的 web api 下载 csv 文件
Posted
技术标签:
【中文标题】从 Angular js 中的 web api 下载 csv 文件【英文标题】:download csv file from web api in angular js 【发布时间】: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 操作不应该在控制器中完成 【参考方案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 是正确的,请在此处查看类似的答案:***.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);
【讨论】:
以上是关于从 Angular js 中的 web api 下载 csv 文件的主要内容,如果未能解决你的问题,请参考以下文章
从 Angular Js(Java Web)调用 API 时出现 CORS 错误
从 Angular JS 调用 Web API 错误:“Access-Control-Allow-Origin”标头包含多个值,因此不允许访问 Origin
在 Web API Core 和 Angular JS 中启用 CORS
如何在没有登录表单的情况下将摘要身份验证与 asp.net web api 和 angular js 一起使用?