概要
管理システムや業務システムを作っているとウェブにtable
タグで表示したものをCSVやExcelで出力したい場面が出てきます。
以前は、サーバーサイドで出力処理を書いていたのですが、「いや、表示したものそのまま出せばサーバーサイドの実装しなくてよね?」ってことで、いろいろ試行錯誤しながらやってみました。
ちなみにこの手のJavaScriptライブラリはあるにはあるのですが、複数のシートに出力するのに対応してなかったりします。
今回は複数のtable
をシートに分けて1つのブックとして出力できるようにしています。
Sheet.js
これはかなり使えそうです。
これを使うと、HTML上の複数のテーブルを1つのExcelブック内にシートに分けて出力することができます。
出力形式は.xlsx
。
デフォルトではそういった関数はないので、少し独自でコードを書く必要はありますが、比較的簡単に実装できます。
必要なファイル
SheetJSは.xls
と.xlsx
に対応したものがありますが、後者のものからdist/xlsx.full.js
またはdist/xlsx.full.min.js
を読み込みます。
ファイルとしてダウンロードさせるにはFileSaver.jsが必要ですので、これも読み込んでおきます。
(サンプルコードやデモはCDNから取得)
実装
この辺りを参考に作ります。
- https://github.com/SheetJS/js-xlsx#html-table-input
- https://github.com/SheetJS/js-xlsx#writing-workbooks
<button type="button" id="dl-xlsx">Download XLSX</button>
<h3>東京都区一覧</h3>
<table class="table-to-export" data-sheet-name="東京都区一覧">
<thead>
<tr><th>番号</th><th>特別区</th><th>推計人口</th><th>面積</th><th>人口密度</th></tr>
</thead>
<tbody>
<tr><td>01</td><td>千代田区</td><td>59,441人</td><td>11.66km2</td><td>5,100人/km2</td></tr>
<tr><td>02</td><td>中央区</td><td>147,620人</td><td>10.21km2</td><td>14,460人/km2</td></tr>
...
<tr><td>23</td><td>江戸川区</td><td>685,899人</td><td>49.90km2</td><td>13,750人/km2</td></tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.9.10/xlsx.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<script src="export-xlsx.js"></script>
document.getElementById('dl-xlsx').addEventListener('click', function () {
var wopts = {
bookType: 'xlsx',
bookSST: false,
type: 'binary'
};
var workbook = {SheetNames: [], Sheets: {}};
document.querySelectorAll('table.table-to-export').forEach(function (currentValue, index) {
// sheet_to_workbook()の実装を参考に記述
var n = currentValue.getAttribute('data-sheet-name');
if (!n) {
n = 'Sheet' + index;
}
workbook.SheetNames.push(n);
workbook.Sheets[n] = XLSX.utils.table_to_sheet(currentValue, wopts);
});
var wbout = XLSX.write(workbook, wopts);
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) {
view[i] = s.charCodeAt(i) & 0xFF;
}
return buf;
}
saveAs(new Blob([s2ab(wbout)], {type: 'application/octet-stream'}), 'test.xlsx');
}, false);
サンプル作りました。
demo
2021.10.13 追記
PHPで書かれたDBアドミニストレーションツールAdminerにExcelエクスポート機能をつけるプラグインを作って見ました。ほぼほぼJavaScriptになってますが。
本家に提案してみたんですが、まだ掲載はされていないみたいです。