新しいことにはウェルカム

技術 | 電子工作 | ガジェット | ゲーム のメモ書き

JavaScriptで、Excelで出力した、改行・カンマ付きCSVファイルを読み込む方法

CSVファイルの読み込みは、今までSheetJSを使っていました。

しかし、どうしても文字化けしてうまく読み込めないCSVファイルがあったので、他のライブラリを試してみることにしました。

npmで「csv」で検索すると一番上に出てくる、その名も「csv」というライブラリがあったので、それを使ってみるとうまくいきました。

「csv」は結構便利な機能があって、今後CSVファイルの読み込みは「csv」を使っていこうと思うので、ざっくり使い方をメモしておきます。

CSVファイルの読み込みはライブラリを使った方がいい

CSVはフォーマットが分かりやすいので、自分で読み込みを書けなくもないです。

しかし、Excelではよく、セルの中に「改行・カンマ」を含むデータを入れたりするのですが、そういったExcelファイルから出力したCSVファイルを読み込もうとすると、処理が面倒になります。

面倒なCSVファイル例

JavaScriptで、Excelで出力した、改行・カンマ付きCSVファイルを読み込む方法

「csv」を使えば、「改行・カンマ」を含んだCSVもうまく読み込んでくれるし、空行を読み飛ばしたり、自動でJSONデータに変換してくれるし、使い方も簡単だし、積極的に使った方が楽かなぁと思います。

インストール

CSV書き込み機能もあるのですが、読み込みしかしないなら「csv-parse」だけをインストールすればOKです。

npm install csv-parse

利用

引数にCSVデータ(文字列)を直接渡して使います。

ファイルからの読み込み機能は無いので、fsでファイルを読み込んでデータを渡します。

import * as parse_csv from 'csv-parse/lib/sync';
import * as fs from 'fs';

const csv = parse_csv(fs.readFileSync('test.csv'),{
    bom: true
});

console.log(csv);
// [
//   [ 'キー1', 'キー2', 'キー3' ],
//   [ '改行・カンマ,\r\n,\r\nを,含むデータ', '', '' ],
//   [ '', '', '' ],
//   [ '#コメント行', '', '' ]
// ]

これだけです!

細かい設定は、2番目の引数に記載していきます。

後述しますが、ExcelからUTF-8でCSV出力した場合はbomの設定がいります。

設定

よく使いそうな設定をまとめておきます。

bom

ExcelからUTF-8でCSV出力すると、BOM付きUTF-8になります。BOM付きUTF-8を読み込む場合、bomtrueにします。

デフォルトはfalseなので、通常のUTF-8のCSVを読み込む場合はbomの設定は不要です。

ちなみに、SheetJSで文字化けしたのは、BOM付きUTF-8が原因でした。

columns

通常、データは配列で取得されるのですが、columnstrueにすると、CSVの1行目をヘッダーとみなして、JSONオブジェクトにして取得してくれます。

const csv = parse_csv( fs.readFileSync('test.csv'),{
    bom: true,
    columns: true
});

console.log(csv);
// [
//   { 'キー1': '改行・カンマ,\r\n,\r\nを,含むデータ', 'キー2': '', 'キー3': '' },
//   { 'キー1': '', 'キー2': '', 'キー3': '' },
//   { 'キー1': '#コメント行', 'キー2': '', 'キー3': '' }
// ]

JSONのキー名を、ヘッダーと違うものにしたい時は、キーを配列で指定して明示的に変えることもできます。

ただしその場合、ヘッダーもデータとして扱われてしまうので、後述するfromで、ヘッダーを読み飛ばすようにする必要があります。

const csv = parse_csv( fs.readFileSync('test.csv'),{
    bom: true,
    columns: ['key1', 'key2', 'key3']
});

console.log(csv);
// [
//   { key1: 'キー1', key2: 'キー2', key3: 'キー3' },
//   { key1: '改行・カンマ,\r\n,\r\nを,含むデータ', key2: '', key3: '' },
//   { key1: '', key2: '', key3: '' },
//   { key1: '#コメント行', key2: '', key3: '' }
// ]

from

データを取得する時、ヘッダー行を飛ばしたい時があります。

fromでデータが始まる行を指定できるので、ヘッダー行を飛ばすことができます。

ただし、行は「0」始まりではなく、「1」始まりなので注意が必要です。つまり、先頭ヘッダーを読み飛ばすにはfromを「2」にします。

const csv = parse_csv( fs.readFileSync('test.csv'),{
    bom: true,
    from: 2,
    columns: ['key1', 'key2', 'key3']
});

console.log(csv);
// [
//   { key1: '改行・カンマ,\r\n,\r\nを,含むデータ', key2: '', key3: '' },
//   { key1: '', key2: '', key3: '' },
//   { key1: '#コメント行', key2: '', key3: '' }
// ]

skip_lines_with_empty_values

skip_lines_with_empty_valuestrueにすると、データの無い行は読み飛ばしてくれます。

const csv = parse_csv( fs.readFileSync('test.csv'),{
    bom: true,
    skip_lines_with_empty_values: true
});

console.log(csv);

// [
//   [ 'キー1', 'キー2', 'キー3' ],
//   [ '改行・カンマ,\r\n,\r\nを,含むデータ', '', '' ],
//   [ '#コメント行', '', '' ]
// ]

comment

commentで指定した文字列で始まる行は、コメント行として読み飛ばしてくれます。

const csv = parse_csv( fs.readFileSync('test.csv'),{
    bom: true,
    comment: '#'
});

console.log(csv);
// [
//   [ 'キー1', 'キー2', 'キー3' ],
//   [ '改行・カンマ,\r\n,\r\nを,含むデータ', '', '' ],
//   [ '', '', '' ]
// ]

relax_column_count

CSVフォーマットは、全ての行の列数は同じである必要があります。

しかし、プログラムや手編集で作成したCSVによっては、列数がまちまちだったりします。

「csv」で列数が異なるCSVを読み込むと、CSV_INCONSISTENT_RECORD_LENGTHというエラーになるのですが、relax_column_counttrueにすると、列数が可変になるのを容認します。

trim

各カラムのデータは文字列として取得されます。

文字列の前後に空白文字があった場合、それら空白文字も含めてデータとして取得されます。

trimtrueにすると、事前に前後の空白を取り除いたものをデータとして取得してくれます。 もちろん、文字列データとして意図的に空白が入っている場合は取り除かれません。

感想など

ライブラリは都度使い方を覚えるのが面倒なのですが、思った以上に簡単でよかった。

参考記事

関連記事

www.kwbtblog.com

関連カテゴリー記事

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com