
目次
ExcelJSでExcelやCSVファイルを出力
Reactで作成しているWebサイトまたはWebアプリで、特定のデータをExcel, CSV, TSVファイルで出力してダウンロードしたいことがあります。
そんなときはExcelJSというJavaScriptライブラリを使用すれば簡単にExcel, CSV, TSVファイルで出力できます。
※ ExcelJSという名前ですが、CSVやTSVファイルも出力できます。
React + ExcelJSでExcelを出力する方法
まず、以下のコマンドでVite + Reactの環境を作成します。
npm create vite@latest my-react-exceljs -- --template react-swc-ts
次にcdでプロジェクトディレクトリに移動して、必要なものをインストールします。
cd my-react-exceljs
npm install
npm i -D exceljs
最後にApp.tsxに以下のコードを貼り付けれると、React + ExcelJSでExcelを出力してダウンロードできるWebページが作成できます。
import ExcelJS from 'exceljs'
const App = () => {
const clickButtonAsync = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault()
const filename = 'sample.xlsx'
const workbook = new ExcelJS.Workbook()
const worksheet = workbook.addWorksheet('My Sheet')
// ヘッダーを追加
worksheet.columns = [
{ header: 'ID', key: 'id' },
{ header: '名称', key: 'name' },
{ header: '価格', key: 'price' }
]
// 行を追加
worksheet.addRows([
{ id: 1001, name: 'りんご', price: 100 },
{ id: 1002, name: 'バナナ', price: 200 },
{ id: 1003, name: 'みかん', price: 300 },
])
// Excelデータをバッファとして取得
const excelBuffer = await workbook.xlsx.writeBuffer()
// Blobを作成(MIMEタイプ: Excel)
const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = filename
a.click()
// リソースを解放
URL.revokeObjectURL(url)
}
return (
<div>
<h1>Download Excel File</h1>
<button onClick={clickButtonAsync}>Download</button>
</div>
)
}
export default App
JavaScriptとReactの基礎が理解できている人であれば、細かく説明しなくてもコードを見ただけで理解していただけるかと思います。
Downloadボタンをクリックすると、Excelファイルがダウンロードできます。
ファイル名を「sample.xlsx」、シート名を「My Sheet」、シート内のデータを配列で追加しているので、それぞれの内容がExcelファイルに反映されていることが確認できます。
React + ExcelJSでCSVを出力する方法
React + ExcelJSでCSVファイルを出力するコードはExcelファイルのときとほとんど同じです。
import ExcelJS from 'exceljs'
const App = () => {
const clickButtonAsync = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault()
const filename = 'sample.csv'
const workbook = new ExcelJS.Workbook()
const worksheet = workbook.addWorksheet('My Sheet')
// ヘッダーを追加
worksheet.columns = [
{ header: 'ID', key: 'id' },
{ header: '名称', key: 'name' },
{ header: '価格', key: 'price' }
]
// 行を追加
worksheet.addRows([
{ id: 1001, name: 'りんご', price: 100 },
{ id: 1002, name: 'バナナ', price: 200 },
{ id: 1003, name: 'みかん', price: 300 },
])
// CSVデータをバッファとして取得
const csvBuffer = await workbook.csv.writeBuffer()
// Blobを作成(MIMEタイプ: text/csv)
const blob = new Blob([csvBuffer], { type: 'text/csv;charset=utf-8;' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = filename
a.click()
// リソースを解放
URL.revokeObjectURL(url)
}
return (
<div>
<h1>Download CSV File</h1>
<button onClick={clickButtonAsync}>Download</button>
</div>
)
}
export default App
Excelのときとの違いは以下の3点だけです。
- ファイル名の拡張子をsample.xlsxからsample.csvに変更
- バッファをExcelからCSVに変更 (workbook.csv.writeBuffer()になる)
- Blob作成時のMIMEタイプをCSVに変更
CSVファイルの生成はExcelJSを使わずにJavaScriptだけでも可能ですが、ExcelJSのCSVのフォーマットにはFast-CSVが内部で使用されています。
Fast-CSVにより「"」のエスケープなどがデフォルトで処理されるので、ExcelJSを使用したほうがCSVファイルの出力が簡単にできます。
Downloadボタンをクリックすると、CSVファイルがダウンロードできます。
ダウンロードしたsample.csvファイルを開くと、以下の内容になっていることが確認できます。
ID,名称,価格
1001,りんご,100
1002,バナナ,200
1003,みかん,300
React + ExcelJSでTSVを出力する方法
React + ExcelJSでTSVファイルを出力するコードはCSVファイルのときとほとんど同じです。
import ExcelJS from 'exceljs'
const App = () => {
const clickButtonAsync = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault()
const filename = 'sample.tsv'
const workbook = new ExcelJS.Workbook()
const worksheet = workbook.addWorksheet('My Sheet')
// ヘッダーを追加
worksheet.columns = [
{ header: 'ID', key: 'id' },
{ header: '名称', key: 'name' },
{ header: '価格', key: 'price' }
]
// 行を追加
worksheet.addRows([
{ id: 1001, name: 'りんご', price: 100 },
{ id: 1002, name: 'バナナ', price: 200 },
{ id: 1003, name: 'みかん', price: 300 }
])
// タブ区切りのオプション
const options = {
formatterOptions: {
delimiter: '\t'
}
}
// CSVデータをバッファとして取得(TSV形式)
const tsvBuffer = await workbook.csv.writeBuffer(options)
// Blobを作成(MIMEタイプ: text/tab-separated-values)
const blob = new Blob([tsvBuffer], { type: 'text/tab-separated-values;charset=utf-8;' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = filename
a.click()
// リソースを解放
URL.revokeObjectURL(url)
}
return (
<div>
<h1>Download TSV File</h1>
<button onClick={clickButtonAsync}>Download</button>
</div>
)
}
export default App
CSVのときとの違いは以下の3点だけです。
- ファイル名の拡張子をsample.csvからsample.tsvに変更
- formatterOptionsで区切り文字を「delimiter: '\t'」に変更
- Blob作成時のMIMEタイプをTSVに変更
バッファをworkbook.tsv.writeBufferにしないよう注意してください。
ExcelJSはTSVを正式にサポートしていないので、CSVファイルの区切り文字をタブ (delimiter: '\t') にして、MIMEタイプをTSVに変更することでTSVファイルとして出力しています。
sample.tsvファイルを開くと以下のようにカンマではなくタブで区切られています。
ID 名称 価格
1001 りんご 100
1002 バナナ 200
1003 みかん 300
ExcelJSのformatterOptions
ExcelJSでは内部でFast-CSVを使用しているので、区切り文字などをオプションで変更することができます。
CSVとして出力するならオプションの変更は不要ですが、前述のTSVファイルの書き出しのようにCSVの形式を特別な理由があって変更する必要があるときは、これらのオプションが役立ちます。
以降にExcelJSでCSVのフォーマットに使用可能なオプションを記載しましたので、参考にしてください。
delimiter
delimiterオプションを指定することで、デフォルトの区切り文字を「,」から別の文字に変更できます。
タブに変更したい場合は、先程のTSVのコードのように delimiter: '\t' を指定します。
const options = {
formatterOptions: {
delimiter: '\t'
}
}
const tsvBuffer = await workbook.csv.writeBuffer(options)
rowDelimiter
rowDelimiterオプションを指定することで、デフォルトの行区切り記号「\n」を変更できます。
主に区切り記号を「\r」や「\r\n」に変更したいときに使用します。
const options = {
formatterOptions: {
rowDelimiter: '\r\n'
}
}
const tsvBuffer = await workbook.csv.writeBuffer(options)
quote
quoteオプションを指定することで、デフォルトのquote「"」を変更することができます。
例えば「quote: "'"」を指定すれば、ダブルクォーテーションではなくシングルクォーテーションが使用されます。
const options = {
formatterOptions: {
quote: "'"
}
}
const tsvBuffer = await workbook.csv.writeBuffer(options)
ID,名称,価格
1001,りんご,'1,000'
1002,バナナ,'2,000'
1003,みかん,'3,000'
escape
escapeオプションでデフォルトのエスケープ文字「"」を変更できます。
デフォルトではダブルクォーテーションはダブルクォーテーションでエスケープを使用しますが、escapeを使用することでバックスラッシュなどに変更できます。
worksheet.addRows([
{ id: 1001, name: 'りんご "TEST"', price: 100 },
{ id: 1002, name: 'バナナ "TEST"', price: 200 },
{ id: 1003, name: 'みかん "TEST"', price: 300 },
])
const options = {
formatterOptions: {
escape: '\\'
}
}
const csvBuffer = await workbook.csv.writeBuffer(options)
ID,名称,価格
1001,"りんご \"TEST\"",100
1002,"バナナ \"TEST\"",200
1003,"みかん \"TEST\"",300
writeBOM
ExcelJSではデフォルトではファイルはUTF-8になっています。
UTF-8 BOMにしたい場合はオプションで「writeBOM: true」を追加します。
const options = {
formatterOptions: {
writeBOM: true
}
}
const csvBuffer = await workbook.csv.writeBuffer(options)
Shift_JISにしたい場合は「npm i iconv-lite」でiconvをインストールして、エンコードをUTF-8からShift_JISに変更してください。
// CSVデータをバッファとして取得(UTF-8)
const csvBuffer = await workbook.csv.writeBuffer()
const utf8String = csvBuffer.toString()
const sjisBuffer = iconv.encode(utf8String, 'Shift_JIS')
// Blobを作成(Shift_JIS エンコード)
const blob = new Blob([sjisBuffer], { type: 'text/csv' })
quoteColumns
常にダブルクォーテーションで囲むようにできるオプションです。
quoteColumns: true を指定することで、すべてがダブルクォーテーションで囲まれます。
const options = {
formatterOptions: {
quoteColumns: true
}
}
const csvBuffer = await workbook.csv.writeBuffer(options)
"ID","名称","価格"
"1001","りんご","100"
"1002","バナナ","200"
"1003","みかん","300"
配列やオブジェクトを使用することで、特定の列のみダブルクォーテーションを適用させることもできます。
const options = {
formatterOptions: {
quoteColumns: {
'価格': true // または [false, false, true]
}
}
}
const csvBuffer = await workbook.csv.writeBuffer(options)
ID,名称,"価格"
1001,りんご,"100"
1002,バナナ,"200"
1003,みかん,"300"
headersとquoteHeaders
headersとquoteHeadersをtrueにすると、ヘッダーのみダブルクォーテーションを適用できます。
const options = {
formatterOptions: {
headers: true,
quoteHeaders: true,
}
}
const csvBuffer = await workbook.csv.writeBuffer(options)
"ID","名称","価格"
1001,りんご,100
1002,バナナ,200
1003,みかん,300
map
指定したindex (列) を編集することができます。
例えばヘッダーを除く1列目 (index: 0) から1000を引いて、3列目 (index: 2) に円の文字を追加する場合は以下のようになります。
const options = {
if (value === 'ID' || value === '価格') return value
map(value: number | string, index: number) {
switch(index) {
case 0:
return +value - 1000;
case 2:
return value + '円';
default:
return value;
}
},
}
const csvBuffer = await workbook.csv.writeBuffer(options)
ID,名称,価格
1,りんご,100円
2,バナナ,200円
3,みかん,300円
まとめ
React + ExcelJSを使用すれば、簡単にExcel, CSV, TSVファイルを出力(ダウンロード)できます。
CSVファイルの出力に関してはオプションで区切り文字やエスケープ文字などを変更することができます。
しかし、デフォルトの状態から変更すると、CSVファイルの一般的書式 (RFC4180)と異なってしまい、Excelなどで正しく表示できなくなってしまうことがあるので、特に理由がなければ変更しないほうが良いです。