Node.jsでcsvファイルを読み書きする

# はじめに
node.jsでcsvを読み書きしたい時があったので，備忘録としてまとめようと思い，この記事を書きました。
streamを使ったやり方など，色々と方法があったのですが，今回は `fs.readFileSync` と `fs.writeFileSync` を用いた方法でやってみました。

# 大まかな流れ
1. 必要なパッケージのダウンロード
2. 読み込むcsvファイルの作成
3. 実行ファイルの作成
4. 実行

# 必要なパッケージのダウンロード
今回は， `csv` というモジュールを使用しますので，以下コマンドを使用してダウンロードします。

```console
$ npm install --save csv
```
- `--save` : package.jsonのdependenciesに追加される

# 読み込むcsvファイルの作成
先頭の行に，カラム名を入れておきます。

```csv:input.csv
name,age,gender
taro,30,man
jiro,28,man
hanako,20,woman 
```

# 実行ファイルの作成

### 実行ファイルの完成形
`input.csv` というcsvファイルを読み込み，行を追加して `output.csv` という名前で出力するコードになっています。

```js:sample.js
// file system モジュールを読み込む
const fs = require('fs');

// csv モジュールの内，必要な機能を読み込む
const parse = require('csv-parse/lib/sync');
const stringify = require('csv-stringify/lib/sync');
 
// csvファイルを読み込む
const inputData = fs.readFileSync('./input.csv', { encoding : 'utf8' });

// 先頭行をcolumnとして扱い，csvデータをparse
const parsedData = parse(inputData, { columns : true });

// 行を追加
parsedData.push({ 'name': 'saburo', 'age': '25', 'gender': 'man'});

// オブジェクトのプロパティを先頭行に記述し，csvデータに変換
const outputData = stringify(parsedData, { header : true });

// csvファイルを出力
fs.writeFileSync('output.csv', outputData, { encoding: 'utf8' });
```
以下で詳細に説明します。

### モジュールの読み込み
```javascript:sample.js（一部）
// file system モジュールを読み込む
const fs = require('fs');

// csv モジュールの内，必要な機能を読み込む
const parse = require('csv-parse/lib/sync');
const stringify = require('csv-stringify/lib/sync');
```
実装に必要なモジュールを読み込みます。（csv-parse と csv-stringfy については，後ほど詳しく説明します。）

### csvファイルを読み込む
```javascript:sample.js（一部）
// csvファイルを読み込む
const inputData = fs.readFileSync('./input.csv', { encoding : 'utf8' });
```
fsモジュールを用いて， `input.csv` を読み込みます。
今回は，オプションで文字コードを `UTF-8` と指定しています。

### csvファイルをオブジェクトに変換
```javascript:sample.js（一部）
// 先頭行をcolumnとして扱い，csvデータをparse
const parsedData = parse(inputData, { columns : true });
```
`fs.readFileSync` でcsvファイルを読み込むと，以下のように単なる文字列として保存されます。

```console:inputDataの中身
name,age,gender
taro,30,man
jiro,28,man
hanako,20,woman
```

これを，javascriptで操作しやすくするためにオブジェクトの形式に変更するのが， **csv-parse** です。
`columns : true` というオプションをつけることによって，csvファイルの先頭行を，オブジェクト変換後のプロパティとして扱います。

```console:parsedDataの中身
[
  { name: 'taro', age: '30', gender: 'man' },
  { name: 'jiro', age: '28', gender: 'man' },
  { name: 'hanako', age: '20', gender: 'woman' }
]
```

### 末尾に行を追加
```javascript:sample.js（一部）
// 行を追加
parsedData.push({ 'name': 'saburo', 'age': '25', 'gender': 'man'});
```

### オブジェクトをcsvデータに変換
```javascript:sample.js（一部）
// オブジェクトのプロパティを先頭行に記述し，csvデータに変換
const outputData = stringify(parsedData, { header : true });
```
**csv-stringify** は， **csv-parse** とは逆に，javascriptのオブジェクトをcsvファイルとして出力するための文字列に変換するモジュールです。
変換されたデータは，以下のような中身になっています。

```console:outputDataの中身
name,age,gender
taro,30,man
jiro,28,man
hanako,20,woman
saburo,25,man
```

### csvファイルを出力
```javascript:sample.js（一部）
// csvファイルを出力
fs.writeFileSync('output.csv', outputData, { encoding: 'utf8' });
```
`fs` モジュールを用いて， `output.csv` という名前でcsvファイルを出力します。

# 実行
```console
$ node sample.js
```

```csv:output.csv
name,age,gender
taro,30,man
jiro,28,man
hanako,20,woman
saburo,25,man
```


# 参考
- [公式ドキュメント](https://csv.js.org/)
- [【Node.js入門】初心者のためのCSV読み込み・JSON変換まとめ！](https://www.sejuku.net/blog/85650)
- [nodeでcsvの読み書き](https://qiita.com/zaburo/items/f7f091c13a69c3b8f935)