LoginSignup
16
22

More than 3 years have passed since last update.

Node.jsでCSVファイルを読みこんでJSONデータに変換するサンプルコード

Last updated at Posted at 2020-02-15

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などで入れておきましょう。
おつかれさまでした。

関連リンク・ソースコード

16
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
22