Javascript 在angular js中从web api下载csv文件
我的API控制器正在返回一个csv文件,如下所示:Javascript 在angular js中从web api下载csv文件,javascript,angularjs,csv,asp.net-web-api,httpresponse,Javascript,Angularjs,Csv,Asp.net Web Api,Httpresponse,我的API控制器正在返回一个csv文件,如下所示: [HttpPost] public HttpResponseMessage GenerateCSV(FieldParameters fieldParams) { var output = new byte[] { }; if (fieldParams!= null) { using (var stream = new MemoryStream())
[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
但没有文件扩展名的文件。
文件的内容是[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();
});
根据中最优秀的答案,最后一个答案对我有效了几个月,然后停止识别文件名,正如adeneo评论的那样 @斯科特在这里的回答对我有用:
我使用了下面的解决方案,它对我有效
if(window.navigator.msSaveOrOpenBlob){
var blob=new blob([decodeURIComponent(encodeURI(result.data))]{
类型:“文本/csv;字符集=utf-8;”
});
msSaveBlob(blob,'filename.csv');
}否则{
var a=document.createElement('a');
a、 href='data:attachment/csv;charset=utf-8',+encodeURI(result.data);
a、 目标='u blank';
a、 下载='filename.csv';
文件.正文.附件(a);
a、 单击();
}
在Chrome 42中,没有一个能为我工作
相反,我的指令现在使用了这个链接
函数(base64
使它工作起来):
链接:函数(范围、元素、属性){
var downloadFile=函数downloadFile(){
var filename=scope.getFilename();
变量链接=角度元素(“”);
link.attr({
href:'data:attachment/csv;base64'+encodeURI($window.btoa(scope.csv)),
目标:“\u blank”,
下载:文件名
})[0]。单击();
$timeout(函数(){
link.remove();
}, 50);
};
元素绑定('click',函数(e){
scope.buildCSV()。然后(函数(csv){
下载文件();
});
作用域:$apply();
});
}
IE不支持a.download。至少在HTML5“受支持”页面上不支持a.download:(与其使用Ajax/XMLHttpRequest/$http调用您的WebApi方法,不如使用html表单。这样,浏览器就可以使用响应头中的文件名和内容类型信息保存文件,而无需绕过javascript在文件处理上的限制。您也可以使用GET方法而不是POST作为method返回数据。下面是一个示例表单:
<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>
文件名是必需的!
出口
我最近不得不实现这一点。我想分享我的想法
为了让它在Safari中工作,我必须设置目标:“_self”。不要担心Safari中的文件名。看起来不支持这里提到的;()
下面的代码在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();
var-anchor=angular.element(“”);
css({display:'none'});
元素(document.body).append(anchor);
anchor.attr({
href:'data:attachment/csv;charset=utf-8,'+encodeURIComponent(数据),
目标:''u self',
下载:“data.csv”
})[0]。单击();
锚定。移除();
在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,
方法:“获取”
})
.然后(功能scb(响应){
var dataResponse=response.data;
//例如,如果response.data为:localhost/export/data.csv
//以下内容将在不更改当前页面位置的情况下下载该文件
window.location='http://'+response.data
},功能(回应){
showWarningNotification($filter('translate')(“global.errorGetDataServer”);
});
可行的解决方案:
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);
}
然后,
content
是一个对象,而不是一个csv字符串。console.logcontent
看看你得到了什么。这是一个字符数组。你能解决这个问题吗?我们也在json对象中获得excel文件的二进制内容。应该使用$http而不是$resource来获得csv字符串;$resource应该可以正常工作有目的地json@Krishna是正确的,请看这里类似的答案:谢谢,这为我节省了很多时间。这就是它的用途!:)DOM操作不应该在控制器中完成
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);
}