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のサーバーからファイルをダウンロードすることに関する他の回答を見ましたが、私のために働くものは見つかりませんでした。これを行う一般的な方法はありますか?シンプルなもののように思えます。
$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
});
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の両方で動作します
この問題に関するほとんどの 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)
これで、ボタンをクリックするたびに、ダウンロードが開始されます。
これは、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();
}
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',
];