encoding.js を利用して Shift_JIS の CSV ファイルを SheetJS で取り込んでみた
こんにちは!DA(データアナリティクス)事業本部 サービスソリューション部の大高です。
SheetJSはExcelデータを扱えるJavaScriptライブラリなのですが、実はCSVファイルも読み込むことが出来ます。
一方で、単純に扱えるCSVファイルは「文字コードをUTF8として保存したCSVファイル」となり、それ以外の文字コードでは文字化けを起こします。また、SheetJS自体にCSVファイルの文字コードを指定して読み込む機能は無いようでした。
そこで今回、encoding.jsを利用することで Shift_JIS の CSV ファイルを文字コード変換し、 SheetJS で取り込む方法について書いていきたいと思います。
前提条件
今回試した環境における各パッケージのバージョンは、以下になります。
- encoding-japanese (encoding.js)
- ^2.0.0
- xlsx (SheetJS)
- 0.18.10
- react-dropzone
- ^14.2.1
- next (NextJS)
- ^11.1.4
- react
- 17.0.2
SheetJSの基本的な使い方については、ここでは触れません。また、ファイルを画面上から取り込むためにreact-dropzoneを利用していますが、こちらも詳細は割愛します。
はじめに
まず最初に「何故 Shift_JIS のCSVを扱おうとしているのか?」について、少し触れておきます。
CSVファイルのデータ元としては「自分で1からエディタで作成する」、「どこかからダウンロードする」というものがありますが、よくあるケースとして 「Excelファイルの内容をCSVとして保存する」 というケースがあるかと思います。
一方で、この場合には往々にして文字コードがShift_JIS
になっており、問題になることが多いです。
最近のバージョンのExcelだったり、明示的に文字コードを指定して保存することでUTF-8
で保存することもできるのですが、良くあるケースとして、この「Shift_JIS のCSVファイルを、SheetJSでどうやって取り込むか」について取り上げています。
encoding.js について
こちらは文字コードの判定や変換をしてくれる素敵な JavaScript ライブラリになります。
利用データとしてUint8Array
などのTypedArray
やNode.js
のBuffer
がサポートされています。
更に README のAPI仕様にも記載されていますが、文字コード変換用のconvert
関数は、「文字コードを自動判定して、目的の文字コードに変換してくれる」という素敵な仕様になっています。(もちろん明示的に指定もできます)
このライブラリがとても強力なので、今回はこのライブラリを利用させていただいています。
encoding.js を SheetJS と組み合わせて利用してみる
では、本題の SheetJS との組み合わせです。具体的なコードとしては以下のようにしました。
import Encoding from 'encoding-japanese' import * as XLSX from 'xlsx/xlsx.mjs' import { WorkBook, WorkSheet } from 'xlsx/xlsx.mjs' (...snip...) export default function FooBar(props) { (...snip...) const onDrop = useCallback( (acceptedFiles) => { acceptedFiles.map(async (file: File) => { let fileData: ArrayBuffer = await file.arrayBuffer() fileData = Encoding.convert(new Uint8Array(fileData), { to: 'UNICODE', type: 'arraybuffer', }) const workbook: WorkBook = XLSX.read(fileData, { type: 'buffer' }) (...snip...)
まず、react-dropzone
を利用してファイルをFile
として扱っています。これを以下のように変換しています。
File (Shift_JIS) ↓ ArrayBuffer (Shift_JIS) ↓ Uint8Array (Shift_JIS) ↓ Encoding.convert で変換 ↓ ArrayBuffer (UNICODE)
そして、最後に SheetJS でファイルを読み込みますが、その際には{ type: 'buffer' }
オプションを指定しています。
これにより、ArrayBuffer
のままExcelのワークブックとして取り込むことができます。
なお、最初はEncoding.convert
で変換する際にarray
として返却し、SheetJS では{ type: 'array' }
として読み込もうとしていたのですが、こちらはうまくいきませんでした。
SheetJS のXLSX.read
のオプションについては、以下が参考になりました。
実際にこのコードを利用して、文字コード変換をする前、文字コード変換をした後の画面サンプルがこちらです。
バッチリ変換できました!
まとめ
以上、encoding.js を利用して Shift_JIS の CSV ファイルを SheetJS で取り込んでみました。
Shift_JIS の CSV ファイルを取り扱うケースは割と多いかなと思われるので、文字コード変換ができるencoding.jsのことを覚えておきたいと思います。
どなたかのお役に立てば幸いです。それでは!