Javascript 在angular js中从web 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())

我的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
但没有文件扩展名的文件。 文件的内容是
[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.log
content
看看你得到了什么。这是一个字符数组。你能解决这个问题吗?我们也在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);
  }