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

时间:2014-01-03 12:54:40

标签: javascript node.js angularjs http http-headers

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

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)
}

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

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

在我的视图中单击带有ng-click的按钮时,会调用此函数:

<button ng-click="csv()">.csv</button>

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

5 个答案:

答案 0 :(得分:111)

$http服务返回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
  });

答案 1 :(得分:21)

关于此问题的大多数references on the web都指出,您无法通过ajax调用“开箱即用”下载文件。我已经看到了(hackish)解决方案涉及iframes以及像@ dcodesmith这样的解决方案,它们的工作方式非常可行。

这是我发现的另一种解决方案,它适用于Angular并且非常简单。

视图中,使用以下csv标记包裹<a>下载按钮:

<a target="_self" ng-href="{{csv_link}}">
  <button>download csv</button>
</a>

(注意那里的target="_self,在ng-app中禁用Angular的路由至关重要here

控制器内,您可以通过以下方式定义csv_link

$scope.csv_link = '/orders' + $window.location.search;

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

现在每次点击按钮,都应该开始下载。

答案 2 :(得分: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

此代码适用于Mozilla和Chrome

答案 3 :(得分: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();
}

答案 4 :(得分:0)

使用angular 1.5.9

我通过将window.location设置为csv文件下载URL使其工作。测试并使用最新版本的Chrome和IE11。

<强>角

   $scope.downloadStats = function downloadStats{
        var csvFileRoute = '/stats/download';
        $window.location = url;
    }

<强> HTML

<a target="_self" ng-click="downloadStats()"><i class="fa fa-download"></i> CSV</a>

php 中为响应设置以下标题:

$headers = [
    'content-type'              => 'text/csv',
    'Content-Disposition'       => 'attachment; filename="export.csv"',
    'Cache-control'             => 'private, must-revalidate, post-check=0, pre-check=0',
    'Content-transfer-encoding' => 'binary',
    'Expires' => '0',
    'Pragma' => 'public',
];