从Angular中的服务器下载text/csv内容作为文件

Mic*_*ael 56 javascript http http-headers node.js angularjs

我正在尝试csv从node.js服务器流式传输文件.服务器部分非常简单:

server.get('/orders' function(req, res) {
  res.setHeader('content-type', 'text/csv');
  res.setHeader('content-disposition', 'attachment; filename='orders.csv');
  return orders.pipe(res); // assuming orders is a csv file readable stream (doesn't have to be a stream, can be a normal response)
}
Run Code Online (Sandbox Code Playgroud)

在我的角度控制器中,我试图做这样的事情

$scope.csv = function() {
    $http({method: 'GET', url: '/orders'});
};
Run Code Online (Sandbox Code Playgroud)

ng-click在我的视图中点击按钮时调用此函数:

<button ng-click="csv()">.csv</button>
Run Code Online (Sandbox Code Playgroud)

我已经查看了有关从Angular中的服务器下载文件的其他答案,但没有找到任何对我有用的内容.有一个共同的方法来做到这一点?似乎应该很简单.

dco*_*ith 112

$httpservice返回一个promise有两个回调方法,如下所示.

$http({method: 'GET', url: '/someUrl'}).
  success(function(data, status, headers, config) {
     var anchor = angular.element('<a/>');
     anchor.attr({
         href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data),
         target: '_blank',
         download: 'filename.csv'
     })[0].click();

  }).
  error(function(data, status, headers, config) {
    // handle error
  });
Run Code Online (Sandbox Code Playgroud)

  • 要使其在Mozilla Firefox上运行,请将锚点附加到document:angular.element(document.body).append(anchor); (8认同)
  • 在Mozilla上Firefox无法运行......在Chrome中运行良好. (7认同)
  • 它虽然以一种hackish方式起作用:第一个chrome的弹出窗口阻止程序阻止了点击,然后当我允许弹出窗口时,它在新窗口中打开下载.反正有没有让它更愉快?如果没有,我想这对我来说已经足够了:) (2认同)

Mic*_*ael 21

网上有关此问题的大多数参考文献都指出,您无法通过ajax调用"开箱即用"下载文件.我见过(hackish)涉及的解决方案,iframes以及像@ dcodesmith这样的解决方案,它们都很有效.

这是我发现的另一种解决方案,它在Angular中工作并且非常直观.

视图中,csv使用<a>以下方式包含带标记的下载按钮:

<a target="_self" ng-href="{{csv_link}}">
  <button>download csv</button>
</a>
Run Code Online (Sandbox Code Playgroud)

(注意target="_self那里,关键是要更加禁用它角的NG信内部应用程序的路由这里)

在您的控制器内,您可以定义csv_link以下方式:

$scope.csv_link = '/orders' + $window.location.search;
Run Code Online (Sandbox Code Playgroud)

($window.location.search如果你想将额外的搜索查询传递给你的服务器,那么它是可选的和onlt)

现在,每次单击该按钮,它都应该开始下载.

  • 这个解决方案与使用带有href评估的简单<a/>标记没有区别. (2认同)

Kom*_*ngh 21

var anchor = angular.element('<a/>');
anchor.css({display: 'none'}); // Make sure it's not visible
angular.element(document.body).append(anchor); // Attach to document

anchor.attr({
    href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data),
    target: '_blank',
    download: 'filename.csv'
})[0].click();

anchor.remove(); // Clean it up afterwards
Run Code Online (Sandbox Code Playgroud)

此代码适用于Mozilla和chrome


Nil*_*ath 7

这对我来说对IE 11 +,Firefox和Chrome都有用.在safari中,它会下载一个文件但是未知,并且未设置文件名.

if (window.navigator.msSaveOrOpenBlob) {
    var blob = new Blob([csvDataString]);  //csv data string as an array.
    // IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
    window.navigator.msSaveBlob(blob, fileName);
} else {
    var anchor = angular.element('<a/>');
    anchor.css({display: 'none'}); // Make sure it's not visible
    angular.element(document.body).append(anchor); // Attach to document for FireFox

    anchor.attr({
        href: 'data:attachment/csv;charset=utf-8,' + encodeURI(csvDataString),
        target: '_blank',
        download: fileName
})[0].click();
anchor.remove();
}
Run Code Online (Sandbox Code Playgroud)