管理画面などでよく見るCSVエクスポート機能ですが、たいていはサーバーサイドでCSVファイルを生成してブラウザにダウンロードさせる、という方法で実装されていると思います。
今回はクライアントサイドで編集したデータをダウンロードする必要があったため、クライアントで完結してCSVファイルを出力する方法を調べてみました。
ポイント
- Blob API(HTML5)でCSVデータをBlobオブジェクトに変換する。
- Internet Expolorerでは、Blobをwindow.navigator.msSaveBlob(IE独自API)で出力する。
- その他のブラウザでは、a要素のdownload属性にファイル名、href属性にBlobで生成した値を指定する。
実装例(AngularJS Service)
(function() {
'use strict';
angular
.module('app')
.service('CsvExporter', CsvExporter);
function CsvExporter($window) {
this.export = function(object, keys) {
var content = keys.join(',') + "\n";
angular.forEach(object, function(properties){
var row = '';
angular.forEach(keys, function(key, index){
if (index != 0) { row += ','; }
if (properties[key]) { row += properties[key]; }
});
content += (row + "\n");
});
var blob = new Blob([ content ], { "type" : "text/csv" });
if ($window.navigator.msSaveBlob) {
$window.navigator.msSaveBlob(blob, "export.csv");
} else {
var link = $window.document.getElementById("csv_exporter");
if (link == null) {
link = $window.document.createElement("a");
link.setAttribute("id", "csv_exporter");
link.setAttribute("style", "display:none;");
link.setAttribute("download", "export.csv");
}
link.setAttribute("href", $window.URL.createObjectURL(blob));
link.click();
}
};
}
})()
DOM操作(a要素の追加)
- AngularJSではDirectiveの利用が推奨されますが、今回はファイル出力のために一時的にa要素を追加するため直接DOMを操作しています。
(ただし、$window Serviceを通してdocumentを参照するようにしています。)
- angular.element(jQuery/jqLite)を利用した場合は下記のように記述できます。
var link = angular.element("#csv_exporter");
if (link.length == 0) {
link = angular.element("<a>");
link.attr("id", "csv_exporter");
link.attr("style", "display:none;");
link.attr("download", "export.csv");
}
link.attr("href", $window.URL.createObjectURL(blob));
link[0].click();
参考