Node.jsでCSVの読み込みや保存をする

Node.jsでCSVファイルを読み込んだり、保存したりする方法です。自前で文字列を操作しなくてもライブラリを使うことで自動でオブジェクトとの変換を行ってくれます。
また、Expressで直接ダウンロードさせるサンプルも載せています。

2022.09.09 サンプルを各モジュールの新しいバージョンに修正しました。

本記事のサンプル動作バージョン

  • csv-parse - 5.3.0
  • csv-stringify - 6.2.0
  • iconv-lite - 0.6.3

CSVファイルを読み込む

csv-parseを使うことで、CSVをオブジェクトの配列や配列の配列に読み込みことができます。

csv-parseのインストール

npm install csv-parse

Excelなどで作成したShift-JISのCSVファイルを開くためにはiconv-liteもインストールします。

npm install iconv-lite

UTF-8で保存したCSVファイルを読み取る - ヘッダー行なしの場合

結果は配列で取得できます。

sample-utf8.csv
001,ABC
002,BCD
003,CDE
"use strict";

const fs = require('fs');
const parse = require('csv-parse/sync');

const data = fs.readFileSync('sample-utf8.csv');
const records = parse.parse(data, {
    columns: false
});

console.log(records);

実行結果

[ [ '001', 'ABC' ], [ '002', 'BCD' ], [ '003', 'CDE' ] ]

UTF-8で保存したCSVファイルを読み取る - ヘッダー行ありの場合

結果はオブジェクトの配列で取得できます。

sample-utf8.csv
No,Value
001,ABC
002,BCD
003,CDE
"use strict";

const fs = require('fs');
const parse = require('csv-parse/sync');

const data = fs.readFileSync('sample-utf8.csv');
const records = parse.parse(data, {
    columns: true
});

console.log(records);

実行結果

[
  { No: '001', Value: 'ABC' },
  { No: '002', Value: 'BCD' },
  { No: '003', Value: 'CDE' }
]

Shift-JISで保存したCSVファイルを読み取る

ファイルから読み込んだデータをiconv.decode()でデコードします。

sample-sjis.csv(Shift-JIS)
Music,Artist
六兆年と一夜物語,和楽器バンド
天樂,和楽器バンド
流星,和楽器バンド
"use strict";

const fs = require('fs');
const parse = require('csv-parse/sync');
const iconv = require('iconv-lite');

const data = fs.readFileSync('sample-sjis.csv');
const str = iconv.decode(data, 'Shift_JIS');
const records = parse.parse(str, {
    columns: true
});

console.log(records);

実行結果(UTF-8で表示)

[
  { Music: '六兆年と一夜物語', Artist: '和楽器バンド' },
  { Music: '天樂', Artist: '和楽器バンド' },
  { Music: '流星', Artist: '和楽器バンド' }
]

オブジェクトの一覧をCSVファイルで保存する

オブジェクトからカンマ区切りへの変換はcsv-stringifyを使用します。あとは変換した文字列をwriteFileSync()で保存すればOKです。

インストール

npm install csv-stringify

こちらもShift-JISで保存するためにはiconv-liteもインストールします。

npm install iconv-lite

ヘッダー出力なしで保存する

オプションのheaderfalseを指定します。

"use strict";

const fs = require('fs');
const stringifySync = require("csv-stringify/sync");

const data = [
    { Music: '六兆年と一夜物語', Artist: '和楽器バンド' },
    { Music: '天樂', Artist: '和楽器バンド' },
    { Music: '流星', Artist: '和楽器バンド' },
];

const csvString = stringifySync.stringify(data, {
    header: false
});

fs.writeFileSync('output.csv', csvString);

output.csv の内容

六兆年と一夜物語,和楽器バンド
天樂,和楽器バンド
流星,和楽器バンド

ヘッダー出力ありで保存する

オプションのheadertrueを指定します。

"use strict";

const fs = require('fs');
const stringifySync = require("csv-stringify/sync");

const data = [
    { Music: '六兆年と一夜物語', Artist: '和楽器バンド' },
    { Music: '天樂', Artist: '和楽器バンド' },
    { Music: '流星', Artist: '和楽器バンド' },
];

const csvString = stringifySync.stringify(data, {
    header: true
});

fs.writeFileSync('output.csv', csvString);

output.csv の内容

Music,Artist
六兆年と一夜物語,和楽器バンド
天樂,和楽器バンド
流星,和楽器バンド

出力する項目を指定する

オプションのcolumnsで出力する項目を指定できます。項目は入力データのプロパティ名で指定します。ヘッダー出力あり・ヘッダー出力なしの場合、どちらでも指定可能です。

配列指定

配列で入力データのプロパティ名を指定します。

"use strict";

const fs = require('fs');
const stringifySync = require("csv-stringify/sync");

const data = [
    { Music: '六兆年と一夜物語', Artist: '和楽器バンド' },
    { Music: '天樂', Artist: '和楽器バンド' },
    { Music: '流星', Artist: '和楽器バンド' },
];

const csvString = stringifySync.stringify(data, {
    header: true,
    columns: [
        'Music',
    ]
});

fs.writeFileSync('output.csv', csvString);
output.csv の内容
Music
六兆年と一夜物語
天樂
流星

オブジェクト指定

オブジェクトで入力データのプロパティ名を指定します。プロパティ名の値がカラム名として出力されます。

"use strict";

const fs = require('fs');
const stringifySync = require("csv-stringify/sync");

const data = [
    { Music: '六兆年と一夜物語', Artist: '和楽器バンド' },
    { Music: '天樂', Artist: '和楽器バンド' },
    { Music: '流星', Artist: '和楽器バンド' },
];

const csvString = stringifySync.stringify(data, {
    header: true,
    columns: {
        Music: '曲',
    }
});

fs.writeFileSync('output.csv', csvString);
保存されたファイルの内容
曲
六兆年と一夜物語
天樂
流星

値を""で囲んで保存する

オプションのquoted_stringtrueを指定します。

"use strict";

const fs = require('fs');
const stringifySync = require("csv-stringify/sync");

const data = [
    { Music: '六兆年と一夜物語', Artist: '和楽器バンド' },
    { Music: '天樂', Artist: '和楽器バンド' },
    { Music: '流星', Artist: '和楽器バンド' },
];

const csvString = stringifySync.stringify(data, {
    header: true,
    quoted_string: true
});

fs.writeFileSync('output.csv', csvString);

保存されたファイルの内容

"Music","Artist"
"六兆年と一夜物語","和楽器バンド"
"天樂","和楽器バンド"
"流星","和楽器バンド"

Shift-JISで保存する

ExcelなどでCSVを開くケースも多いと思います。その場合Shift-JISで保存しておく必要があります。
Node.jsでは保存前にiconv.encode()で文字列をエンコードすることでShift-JISで保存できます。

"use strict";

const fs = require('fs');
const stringifySync = require("csv-stringify/sync");
const iconv = require('iconv-lite');

const data = [
    { Music: '六兆年と一夜物語', Artist: '和楽器バンド' },
    { Music: '天樂', Artist: '和楽器バンド' },
    { Music: '流星', Artist: '和楽器バンド' },
];

const csvString = stringifySync.stringify(data, {
    header: true
});

const csvStringSjis = iconv.encode(csvString, 'Shift_JIS');
fs.writeFileSync('output.csv', csvStringSjis);

ExpressでCSVを直接ダウンロードさせる

Expressでサーバーのストレージに保存することなく、クライアントにCSVをダウンロードさせるサンプルです。

"use strict";

const fs = require('fs');
const stringifySync = require("csv-stringify/sync");
const iconv = require('iconv-lite');

const http = require('http');
const express = require('express');
const app = express();

let webServer = http.createServer(app)
    .listen(8080, () => {
        console.log('server start');
    });

app.get('/download-csv', (request, response) => {
    const data = [
        { Music: '六兆年と一夜物語', Artist: '和楽器バンド' },
        { Music: '天樂', Artist: '和楽器バンド' },
        { Music: '流星', Artist: '和楽器バンド' },
    ];

    const csvString = stringifySync.stringify(data, {
        header: true,
        quoted_string: true
    });

    response.set('Content-disposition', 'attachment; filename=download.csv');
    response.set('Content-Type', 'text/csv; charset=Shift_JIS');
    response.send(iconv.encode(csvString, 'Shift_JIS'));
});

ブラウザでhttp://localhost:8080/download-csvにアクセスすると、download.csvがダウンロードされます。

UTF-8で保存したい場合は、responseを次のように変更してください。

response.set('Content-disposition', 'attachment; filename=download.csv');
response.set('Content-Type', 'text/csv; charset=utf-8');
response.send(csvString);
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

スポンサードリンク

関連コンテンツ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です