web-dev-qa-db-ja.com

Angularのサーバーからファイルとしてtext / csvコンテンツをダウンロードします

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

angularコントローラーでは、このようなことをしようとしています

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

この関数は、私のビューでng-clickのボタンをクリックすると呼び出されます:

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

私はAngularのサーバーからファイルをダウンロードすることに関する他の回答を見ましたが、私のために働くものは見つかりませんでした。これを行う一般的な方法はありますか?シンプルなもののように思えます。

55
Michael

$httpサービスは、以下に示すように2つのコールバックメソッドを持つ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
  });
111
dcodesmith
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の両方で動作します

21
Komal Singh

この問題に関するほとんどの Web上のリファレンス は、「箱から出して」ajax呼び出しを介してファイルをダウンロードできないという事実を指摘しています。 iframesを含む(ハック的な)ソリューションと、@ dcodesmithのように機能し、完全に実行可能なソリューションを見てきました。

Angularで機能し、非常に簡単な別のソリューションを次に示します。

viewで、csvダウンロードボタンを<a>タグで次のようにラップします。

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

target="_selfがあることに注意してください。ng-app内でAngularのルーティングを無効にすることが重要です here

Yourecontroller内で、csv_linkを次の方法で定義できます。

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

$window.location.searchはオプションであり、追加の検索クエリをサーバーに渡す場合はonlt)

これで、ボタンをクリックするたびに、ダウンロードが開始されます。

21
Michael

これは、IE 11 +、Firefox、Chromeで私にとってうまくいったことです。サファリでは、ファイルをダウンロードしますが、不明としてファイル名が設定されていません。

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();
}
7
Nilath

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',
];
0
forsimb