[英]download csv file from web api in angular js
我的 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 中,不会下载任何内容。
我能做些什么来解决这个问题?
更新:这可能对你们有同样问题的人有用: 链接
试试看:
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();
});
基于这个问题中最优秀的答案
我使用了以下解决方案,它对我有用。
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(); }
最后一个答案对我有用了几个月,然后停止识别文件名,正如 adeneo 评论的那样......
@Scott 的回答对我有用:
在 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();
});
}
我最近不得不实施这个。 想分享我的想法;
为了让它在 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();
与其使用 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>
在 Angular 1.5 中,使用$window
服务下载文件。
angular.module('app.csv').factory('csvService', csvService);
csvService.$inject = ['$window'];
function csvService($window) {
function downloadCSV(urlToCSV) {
$window.location = urlToCSV;
}
}
IE 不支持 a.download。 至少在 HTML5“支持”的页面上。 :(
我认为下载 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")); });
可行的解决方案:
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.