【React】Excelファイルの読み込み → json 変換の実装(SheetJS js-xlsx の利用)
今回、Excel ファイルをブラウザで読み込み、json に変換して、API で POST する処理を実装したので、備忘録として残しておく。本記事では、Excel ファイルをブラウザで読み込み、json に変換するまでのコードを紹介する。
SheetJS js-xlsx
今回、Excel ファイルを取り扱うにあたり、「SheetJS js-xlsx」というライブラリを用いた。
このライブラリを使うことで、ブラウザ上で Excel ファイルを自由に操作することができる。
本当に便利なライブラリであると思えた。
インストールは以下の通りである。
$ yarn add xlsx
サンプルコード
以下のように、Excel ファイルをブラウザで読み込み、json に変換して表示するまでのサンプルコードとなっている。

import React, { useRef, useState } from 'react' import XLSX from 'xlsx' const Component = () => { const fileInput = useRef<HTMLInputElement>(null) const [fileName, setFileName] = useState('') const [excelData, setExcelData] = useState('') const handleTriggerReadFile = () => { if (fileInput.current) { fileInput.current.click() } } const handleReadFile = (fileObj: File) => { if (fileObj) { setFileName(fileObj.name) fileObj.arrayBuffer().then((buffer) => { const workbook = XLSX.read(buffer, { type: 'buffer', bookVBA: true }) const firstSheetName = workbook.SheetNames[0] const worksheet = workbook.Sheets[firstSheetName] const data = XLSX.utils.sheet_to_json(worksheet) setExcelData(JSON.stringify(data)) }) } } return ( <div style={{ padding: '20px' }}> <p style={{ paddingBottom: '20px' }}>Excelファイルをアップロードする</p> <button onClick={() => handleTriggerReadFile()}>ファイル選択</button> {!!fileName && <span>ファイル名:{fileName}</span>} <form style={{ display: 'none' }}> <input type="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ref={fileInput} onChange={(e) => { e.preventDefault() handleReadFile(e.currentTarget.files[0]) }} /> </form> {!!excelData && ( <div style={{ border: 'solid 1px #444', marginTop: '10px', padding: '10px', }} > {excelData} </div> )} </div> ) } export default Component
通常の form の input ボタンを押して、ファイルを選択してもいいが、button を押すことでファイルを選択できるような実装にしている。
const fileInput = useRef<HTMLInputElement>(null) const handleTriggerReadFile = () => { if (fileInput.current) { fileInput.current.click() } } ~省略~ <button onClick={() => handleTriggerReadFile()}>ファイル選択</button> <form style={{ display: 'none' }}> <input type="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ref={fileInput} onChange={(e) => { e.preventDefault() handleReadFile(e.currentTarget.files[0]) }} /> </form>
useRef を用いて input を参照させて、button を Click した際に、参照した input を Click したようにするようにしている。
また、inputに関しては、accept 属性を用いて、Excel ファイルしか選択できないようにしている。
ファイルが選択されると、onChangeイベントが発火して、以下の処理が実行される。
const handleReadFile = (fileObj: File) => { if (fileObj) { setFileName(fileObj.name) fileObj.arrayBuffer().then((buffer) => { // ファイルを読み込む const workbook = XLSX.read(buffer, { type: 'buffer', bookVBA: true }) // 最初のシート名を取得する const firstSheetName = workbook.SheetNames[0] // 最初のシート名から、ワークシートを取得する const worksheet = workbook.Sheets[firstSheetName] // シートのデータを JSON として取得する const data = XLSX.utils.sheet_to_json(worksheet) // JSON 文字列として state に保存する setExcelData(JSON.stringify(data)) }) } }
FileReader.readAsArrayBuffer() を用いて実装することもできるが、今回新しいAPIである Blob.arrayBuffer() で実装を行った。Blob.arrayBuffer() はPromiseが返却されるので、処理が非常に書きやすかった。FileReader の場合は、以下のようにイベントハンドラを設定しなくてはいけなかった。
const reader = new FileReader() reader.onload = (e) => { const buffer = e.target.result // bufferの処理 } reader.readAsBinaryString(fileObject)
Excel ファイルの読み込みに関しては、一部抜粋しているコードの部分にコメントを追記しているので参考にして欲しい。
まとめ
「SheetJS js-xlsx」という便利なライブラリのおかげで、意外に簡単に、Excelファイルの読み込みを実装することができた。本当にライブラリに感謝である。
それでは、ステキな開発ライフを。