JavaScriptのencoding.jsでShift-JISのCSVを扱う

JavaScriptでShift-JISのデータを扱うのが思っていた以上に面倒でした。

出来ればShift-JISのCSVを読み込んだり作成したりしたくありませんが、行政書類とかはShift-JISしか受け付けなかったりします。

仕方がないのでJavaScriptでShift-JISとUNICODEの変換に対応していきます。

面倒の極みですね。

encoding.jsがないと始まらない

私は、自分でShift-JISとUNICODEのコンバートは出来ないので、encoding.jsを使います。

https://github.com/polygonplanet/encoding.js/blob/master/README_ja.md

Shift-JISのCSVファイルを読み込み

HTMLファイル

<input id="read-csv" type="file" accept=".csv" onchange="readCsv(event)">

JavaScript

Shift-JISのCSVファイルを読み込んでUNICODEに変換します。

import Encoding from 'encoding-japanese';

const readCsv = (event) => {
    const file = event.target.files[0];
    const reader = new FileReader();

    reader.addEventListener( 'load' , () => {
        const result = reader.result;
        const unicodeCsv = Encoding.convert(
            result,
            {
                to: 'UNICODE',
                from: 'SJIS'
            }
        );
    
        // 後述の関数でArrayに変換
        const arrayFromCsv = csvToArray(unicodeCsv);

        // 何らかのやりたい処理
    });

    reader.readAsBinaryString(file);
}

注意:readAsBinaryStringでないと上手く変換できません。

CSVを配列に変換

CSVファイルを読み込んだだけだと使いにくいので、配列に変換します。

const csvToArray = (unicodeCsv) => {
    const tmp = unicodeCsv.split('\r\n');
    const lines = tmp.map( line => {
        if ( line.length !== 0 ) {
            return line.split(',');
        }
    }).filter( line => typeof line !== 'undefined' );

    return lines;
}

Shift-JISのCSVファイルを作成

前段階として、CSV用のデータを作成する必要があります。

const createCsv = () => {
    // これまでに他の処理でCSV用のデータを作成
    const unicodeDataForCsv = '作成したデータ';

    // Shift-JISに変換するためにstringToCodeが必要
    const unicodeData = Encoding.stringToCode(unicodeDataForCsv);

    const sjisData = Encoding.convert(
        unicodeData,
        {
            to: "SJIS",
            from: "UNICODE"
        }
    );

    // CSVに変換するにはUnit8Arrayが必要
    const sjisDataForCsv = new Uint8Array(sjisData);

    // ここからはCSVの作成とダウンロード処理
    let filename = 'ファイル名';
    let blob = new Blob([sjisDataForCsv], {type: 'text/csv'});
    let uri = URL.createObjectURL(blob);
    let link = document.createElement('a');
    link.download = filename;
    link.href = uri;
    link.click();
    link.remove();
}

よく分かっていませんが、Shift-JISのCSVに変換するためには以下2点の処理が必要でした。

  • Shift-JISに変換する前に、Encoding.stringToCode
  • CSVに変換するために、Uint8Array