CSVファイルの読み込みは、今までSheetJSを使っていました。
しかし、どうしても文字化けしてうまく読み込めないCSVファイルがあったので、他のライブラリを試してみることにしました。
npmで「csv」で検索すると一番上に出てくる、その名も「csv」というライブラリがあったので、それを使ってみるとうまくいきました。
「csv」は結構便利な機能があって、今後CSVファイルの読み込みは「csv」を使っていこうと思うので、ざっくり使い方をメモしておきます。
CSVファイルの読み込みはライブラリを使った方がいい
CSVはフォーマットが分かりやすいので、自分で読み込みを書けなくもないです。
しかし、Excelではよく、セルの中に「改行・カンマ」を含むデータを入れたりするのですが、そういったExcelファイルから出力したCSVファイルを読み込もうとすると、処理が面倒になります。
面倒な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を読み込む場合、bom
をtrue
にします。
デフォルトはfalse
なので、通常のUTF-8のCSVを読み込む場合はbom
の設定は不要です。
ちなみに、SheetJSで文字化けしたのは、BOM付きUTF-8が原因でした。
columns
通常、データは配列で取得されるのですが、columns
をtrue
にすると、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_values
をtrue
にすると、データの無い行は読み飛ばしてくれます。
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_count
をtrue
にすると、列数が可変になるのを容認します。
trim
各カラムのデータは文字列として取得されます。
文字列の前後に空白文字があった場合、それら空白文字も含めてデータとして取得されます。
trim
をtrue
にすると、事前に前後の空白を取り除いたものをデータとして取得してくれます。
もちろん、文字列データとして意図的に空白が入っている場合は取り除かれません。
感想など
ライブラリは都度使い方を覚えるのが面倒なのですが、思った以上に簡単でよかった。