Node.jsでShift_JIS で書かれたCSVファイルを取り扱う必要があり、その際の備忘メモ。
JSON変換までできた方が便利なので、csvtojson を使ってみました。
要約
- csvtojsonを使えば、標準的なCSVファイルを簡単にJSONデータに変更できました。
- Node.jsはファイル読み込みは基本UTF-8を想定しているようですが、UTF-8以外の場合は iconv-liteをかましてShift_JIS→UTF-8変換してあげればOKでした。
- csvtojson はコマンドラインからも呼び出せるので、コマンドラインでCSV→JSON変換できるのはなにげに便利です。
前提や環境
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.3
BuildVersion: 19D76
$ node --version
v10.16.2
$
ちなみにサンプルデータは 住所.jp という日本の住所情報を用いてみました。
やってみる
$ git clone --branch 0.1.0 https://github.com/masatomix/csv-sample-node.git
$ cd csv-sample-node/
$ npm install
落としてきたプロジェクトのディレクトリ構成はこんな感じです。処理対象のcsvファイル(13tokyo.csv
)だけは、上記サイト から落としておきましょう。
$ tree
.
├── data
│ └── 13tokyo.csv ←読み込むCSVファイル
├── src
│ └── index.ts
├── dist
│ ├── index.js
│ └── index.js.map
├── package.json
└── tsconfig.json
ソースコードはこんな感じ。
index.ts
import fs from 'fs'
import iconv from 'iconv-lite'
import csv from 'csvtojson'
/**
* 指定したパスのcsvファイルをロードして、JSONオブジェクトとしてparseする。
* 全行読み込んだら完了する Promise を返す。
* @param path
*/
const parse = (path: string): Promise<any[]> => {
return new Promise((resolve, reject) => {
let datas: any[] = []
fs.createReadStream(path)
.pipe(iconv.decodeStream('Shift_JIS'))
.pipe(iconv.encodeStream('utf-8'))
.pipe(csv().on('data', data => datas.push(JSON.parse(data)))) // 各行読んだらココが呼ばれるので配列にpush
.on('end', () => resolve(datas)) // 全部終わったらココにくるので、resolveする
})
}
if (!module.parent) {
// 呼んでみる
parse('./data/13tokyo.csv').then((results: any[]) => {
// 郵便番号が「100-000x」のものに絞ってみた
results = results.filter(address => address['郵便番号'].startsWith('100-000'))
console.table(results)
// for (const address of results) {
// console.log(address)
// }
})
}
実行してみます。
$ npm run dev
> csv-sample-node@0.1.0-SNAPSHOT dev /Users/xxx/git/csv-sample-node
> ts-node src/index.ts
┌─────────┬─────────────┬────────┬─────────┬─────────────┬────────────┬────────┬───────┬───────┬──────────┬────────┬────────┬────────┬────────────┬──────────┬───────┬───────┬──────────┬────┬──────┬────────┬───────┬───────┐
│ (index) │ 住所CD │ 都道府県CD │ 市区町村CD │ 町域CD │ 郵便番号 │ 事業所フラグ │ 廃止フラグ │ 都道府県 │ 都道府県カナ │ 市区町村 │ 市区町村カナ │ 町域 │ 町域カナ │ 町域補足 │ 京都通り名 │ 字丁目 │ 字丁目カナ │ 補足 │ 事業所名 │ 事業所名カナ │ 事業所住所 │ 新住所CD │
├─────────┼─────────────┼────────┼─────────┼─────────────┼────────────┼────────┼───────┼───────┼──────────┼────────┼────────┼────────┼────────────┼──────────┼───────┼───────┼──────────┼────┼──────┼────────┼───────┼───────┤
│ 0 │ '100000000' │ '13' │ '13101' │ '131010000' │ '100-0000' │ '0' │ '0' │ '東京都' │ 'トウキョウト' │ '千代田区' │ 'チヨダク' │ '' │ ' ' │ '(該当なし)' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │
│ 1 │ '100000400' │ '13' │ '13101' │ '131010006' │ '100-0004' │ '0' │ '0' │ '東京都' │ 'トウキョウト' │ '千代田区' │ 'チヨダク' │ '大手町' │ 'オオテマチ' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │
│ 2 │ '100000200' │ '13' │ '13101' │ '131010039' │ '100-0002' │ '0' │ '0' │ '東京都' │ 'トウキョウト' │ '千代田区' │ 'チヨダク' │ '皇居外苑' │ 'コウキョガイエン' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │
│ 3 │ '100000100' │ '13' │ '13101' │ '131010045' │ '100-0001' │ '0' │ '0' │ '東京都' │ 'トウキョウト' │ '千代田区' │ 'チヨダク' │ '千代田' │ 'チヨダ' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │
│ 4 │ '100000300' │ '13' │ '13101' │ '131010051' │ '100-0003' │ '0' │ '0' │ '東京都' │ 'トウキョウト' │ '千代田区' │ 'チヨダク' │ '一ツ橋' │ 'ヒトツバシ' │ '' │ '' │ '1丁目' │ '01チョウメ' │ '' │ '' │ '' │ '' │ '' │
│ 5 │ '100000500' │ '13' │ '13101' │ '131010055' │ '100-0005' │ '0' │ '0' │ '東京都' │ 'トウキョウト' │ '千代田区' │ 'チヨダク' │ '丸の内' │ 'マルノウチ' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │
│ 6 │ '100000600' │ '13' │ '13101' │ '131010057' │ '100-0006' │ '0' │ '0' │ '東京都' │ 'トウキョウト' │ '千代田区' │ 'チヨダク' │ '有楽町' │ 'ユウラクチョウ' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │ '' │
└─────────┴─────────────┴────────┴─────────┴─────────────┴────────────┴────────┴───────┴───────┴──────────┴────────┴────────┴────────┴────────────┴──────────┴───────┴───────┴──────────┴────┴──────┴────────┴───────┴───────┘
$
ちゃんとShift_JISのCSVを読み込めています。
また、CSVの1行目のヘッダ行の文字列をJSONデータのプロパティ名として扱えてますね。簡単です。
おまけ: コマンドラインから使ってみる
npmに付属しているnpx
コマンドを使うことで、csvtojsonをコマンドラインから呼び出せます。
$ npx csvtojson ./data/13tokyo.csv
{"�Z��CD":"101841500","�s���{��CD":"13","�s�撬��CD":"13101","����CD":"131010019","�X�֔ԍ�":"101-8415","���Ə��t���O":"1","�
$
あー Shift_JISはダメですね。ということでnkf
をかましてみます。
$ cat ./data/13tokyo.csv | nkf -S | npx csvtojson
{"住所CD":"101006101","都道府県CD":"13","市区町村CD":"13101","町域CD"
$
nkf
コマンドは適宜Homebrewなどで入れておきましょう。
おつかれさまでした。