node-csvを使って、同期的にCSV生成を行う(Sync API)
調べてみたところ、意外とCSV生成に関する同期的な処理の情報が見つからないように思えたので、備忘録として残しておきます。
(Callback API
やStream API
を使ったやり方については見つかりました)
ちなみにCallback API
もStream API
も、今回書くSync API
を使った方法も、下記の公式ドキュメントを見れば一発で見つかるので、そもそも下記のリンクを見れば解決できます。
ここでは、せっかく調べたので同期処理(Sync API)を用いた場合のcsv生成サンプルを書いておこうと思います。
node-csvを使う
使用するライブラリはnode-csv(github)を使います。
公式サイトはこちら(CSV for Node.js)
インストールは下記のコマンドで行います。
yarn add csv
# or
npm install csv
ただ、こちらはパッケージが csv-generate
, csv-parse
, stream-transform
, csv-stringify
に分かれているので、node-csvの機能をフルに使うとかでない限りは個別にインストールすることでも要件は満たせます。
CSV生成には csv-stringify
を使うので、今回の場合インストールは下記のコマンドとなります。
yarn add csv-stringify
# or
npm install csv-stringify
ここらへんの説明については、ググると結構ヒットする気がしているので、割愛します。
csv-stringifyを使ってCSV生成を行う
Sync API
を使う場合、require("csv-stringify/lib/sync")
という形で読み込む必要があります。
サンプルコードです。
const fs = require("fs");
const stringify = require("csv-stringify/lib/sync");
const data = [
{
id: 1,
name: "hoge",
age: 17
},
{
id: 2,
name: "fuga",
age: 21
},
{
id: 3,
name: "piyo",
age: 13
}
];
const csvData = stringify(data, { header: true });
fs.writeFileSync("./sample.csv", csvData);
上のコードを実行すると、下記のようなCSV
ファイルがカレントディレクトリに生成されます。
id,name,age
1,hoge,17
2,fuga,21
3,piyo,13
Object
の項目名がそのままカラム名として処理されているのがわかるかと思います。
CSVのカラム名の生成ルールについて
ちなみにcsv-stringify
の動作的にカラム名は、配列の1つ目のObjectの項目名を見て、カラム名を生成
しているようです。
そのため、下記のようにコードを変更(一つ目のObjectに項目を追加)すると、
diff --git a/main.js b/main.js
index 83568af..b8318c9 100644
--- a/main.js
+++ b/main.js
@@ -6,7 +6,8 @@ const stringify = require("csv-stringify/lib/sync");
{
id: 1,
name: "hoge",
- age: 17
+ age: 17,
+ country: "Japan"
},
{
id: 2,
CSVにもcountry
というカラム名が追加されます。
2つ目と3つ目のobjectにはそのような項目は存在しないため、空になっています。
id,name,age,country
1,hoge,17,Japan
2,fuga,21,
3,piyo,13,
次に2つ目のObjectだけに同じようにcountry
を追加してみます。
(1つ目、3つ目のObjectには追加しません)
diff --git a/main.js b/main.js
index 83568af..380cafe 100644
--- a/main.js
+++ b/main.js
@@ -11,7 +11,8 @@ const stringify = require("csv-stringify/lib/sync");
{
id: 2,
name: "fuga",
- age: 21
+ age: 21,
+ country: "Japan"
},
{
id: 3,
この場合、生成されるCSVファイルは下記のようになり、country
というカラムが認識されていないことが動作からわかるかと思います。
id,name,age
1,hoge,17
2,fuga,21
3,piyo,13
CSV生成時のオプションについて
ちなみに今回はstringify(data, { header: true })
という形で{header: true}
のオプションを指定しているので、カラム名がついていますが、ここを省くと、下記のように省くことも可能です。
1,hoge,17
2,fuga,21
3,piyo,13
option周りについてはこちらを参照すればOKかと思います。