今回はJavaScriptでExcel/CSV両方出力できる機能を実装する方法を解説します。
ExcelだけやCSVだけならライブラリもやり方も色々ありそうでしたがライブラリを2つ入れるは面倒なので、1つのライブラリで両方出力できてなるべく簡単そうなものを探した結果、「exceljs」が良さそうだったのでこれを使って実装します。
管理画面でテーブルのデータをExcel/CSVで出力したいときなどに使えそうです。
デモ
今回作るデモをCodeSandboxで作ってみました。
Excel用とCSV用に2つボタンを用意してもいいのですが、今回はラジオボタンで出力形式を選択できるようにしてみました。
上の埋め込みは実際には動かないので、ダウンロードを試してみたい人は以下のURLからどうぞ。
exceljsでExcel/CSV両方で出力できる機能を実装する方法
まずはexceljsをインストール。
npm i exceljs
コードはこんな感じです。Vue2で書いていますがReactでも似たように書けるはずです。
<template>
<div>
<input type="radio" v-model="type" value="xlsx" />Excel
<input type="radio" v-model="type" value="csv" />CSV
<br />
<button type="button" @click="onExport(type)">ダウンロード</button>
</div>
</template>
<script>
import ExcelJS from 'exceljs';
export default {
data() {
return {
type: 'xlsx', // 初期値
};
},
methods: {
async onExport(ext) {
// ①初期化
const workbook = new ExcelJS.Workbook(); // workbookを作成
workbook.addWorksheet('シート名'); // worksheetを追加
const worksheet = workbook.getWorksheet('シート名'); // 追加したworksheetを取得
// ②データを用意
// 各列のヘッダー
worksheet.columns = [
{ header: 'ID', key: 'id' },
{ header: '名前', key: 'name' },
{ header: '値段', key: 'price' },
];
// 各行のデータ(worksheet.columnsのkeyがオブジェクトのキーと同じになる)
worksheet.addRows([
{
id: 1,
name: 'りんご',
price: 200,
},
{
id: 2,
name: 'ぶとう',
price: 150,
},
{
id: 3,
name: 'ばなな',
price: 180,
}
]);
// ③ファイル生成
const uint8Array =
ext === 'xlsx'
? await workbook.xlsx.writeBuffer() // xlsxの場合
: await workbook.csv.writeBuffer(); // csvの場合
const blob = new Blob([uint8Array], { type: 'application/octet-binary' });
const a = document.createElement('a');
a.href = (window.URL || window.webkitURL).createObjectURL(blob);
a.download = `output.${ext}`;
a.click();
a.remove()
},
},
};
</script>
まずexceljsで出力する際はasync function()
にする点に気をつけましょう(await workbook.xlsx.writeBuffer()
の戻り値がPromiseなので)。
new ExcelJS.Workbook();
でワークブックを作成します。ワークブックはファイル本体のことですね。
workbook.addWorksheet('シート名');
でシートを作成し引数でシート名を指定します。このシートをworkbook.getWorksheet('シート名');
で取得してデータを入れていくわけです。
worksheet.columns
の部分は各列のヘッダーになります。header
は実際に表示されるテキスト、key
は各列(row)にデータを入れていく際に使用するキーです。
worksheet.addRows();
で各行にデータを入れていきます。配列オブジェクトで渡し、1オブジェクト=1行ですね。
各行のオブジェクトのキーはworksheet.columns
の各列のオブジェクトのkey
と同じにする必要があります。これによってどの場所にどのデータが入るのか指定しています。
await workbook.xlsx.writeBuffer()
でExcelファイルを出力します。xlsx
の部分をcsv
に変えるとCSVで出力できるので分岐させるといい感じです。
あとは引数で渡した拡張子でExcel/CSVを分岐してダウンロード処理を書けばokです。aタグを作ってhref
とdownload
属性を入れたらclick()
でクリックイベントを起こし、最後にremove()
で削除します。
a.download = `output.${ext}`;
の部分はダウンロードされるファイル名になります(${ext}
にはxlsx
かcsv
のどちらかが入ります)。
exceljsで他にできること
exceljsでは背景色や文字色などのスタイルも持たせられるみたいです。ライブラリによってできたりできなかったりするので地味に嬉しいかも。列の幅を変えたりもできるみたいです。
またすでにあるExcelファイルを読み込んでデータを追加したり色々できます。まあこのへんは必要に応じて色々調べてみてください。
今回参考にしたリンクも張っておきます。ドキュメントの量がかなり多いので頑張って読めば大体のことはできる気がします。
>>githubドキュメント:exceljs/exceljs: Excel Workbook Manager
>>[React / JavaScript] データのExcel/CSV出力機能を実装する