node.jsのfs.writeFile()を使って、Windows Excelに対応したCSVファイルやTSVファイルを書き出す方法についてまとめたいと思います。

先に結論ですが、CSVファイルはShift-JIS形式でカンマ区切りのデータを書き出す必要があり、一方でTSVファイルはUTF-16LE(リトルエンディアン) BOM付きでタブ区切りのデータを書き出す必要があります。

ファイル形式 名称 文字コード
CSV カンマ区切りファイル Shift-JIS
TSV タブ区切りファイル Unicode( UTF-16LE BOM付き ) ※Windows Excel 2000

また、node.jsではShift-JISやUTF-16LEの文字コードで書き出す事はできないため、文字コード変換にiconv-liteを活用するのが便利です。

当記事では、これらの手順について詳しく後述していきたいと思います。

目次

develop or drink ?
 develop or drink ? ©

CSVとTSVって何?

CSVとはカンマ区切りと改行によって、Excelの列や行が定義されたデータのことです。これに対して、TSVはタブ区切りと改行で定義されたデータの事です。

CSVの一例を挙げると以下のようなテキスト形式となっています。

sample.csv
1
2
3
4
果物,色,価格
りんご,赤,300
バナナ,黄,100
...

前述の通り、カンマで各列を別けて定義し、改行によって列を定義しています。一方でTSVの場合は以下のようになります。

sample.csv
1
2
3
4
果物	色	価格
りんご 赤 300
バナナ 黄 100
...

CSVとは異なり、各列はタブによって区別されています。またはCSVと同様に、ファイル拡張子は.csvと指定するとExcelから開く事ができます。

文字コードの扱いが違うので注意

先程取り上げたCSVファイルとTSVファイルですが、Excelで扱っている文字コードがそれぞれ異なるので、注意が必要です。

ファイル形式 文字コード
CSV Shift-JIS
TSV Unicode( UTF-16LE BOM付き )

実際にCSVまたはTSVを書き出す際には、上記で挙げた文字セットを指定してファイルを書き出す事になります。

Shift-JISやUTF-16形式で書き出す

node.jsからjavascriptを使ってファイルを書き出す際には、fs.writeFile()を使います。ただし、node.jsはShift-JIS等をサポートしていないので、通常の方法で書き込むと、文字化けしてしまいます。

そこで、npmパッケージのiconv-liteを使います。iconv-liteは様々な文字コードを変換するモジュールです。iconv-liteの使い方については以下の記事をご覧ください。

CSVをnode.jsを使って書き出す(Shift-JIS)

それでは、CSVのファイルをnode.jsで書き出す簡単なサンプルコードを載せてみたいと思います。まずはiconv-liteをnpmインストールします。

bash
1
2
$ npm init
$ npm install iconv-lite --save

続いて、node.jsのコードを作成し、以下のように記述します。

bash
1
$ vim csv.js

注目したいポイントは、下記のコードのようにiconv.encode()メソッドでShift_JISを指定することです。

csv.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 以下はES6で記述されており、node.js v8で動作します。
const fs = require('fs')
const path = require('path')
const iconv = require('iconv-lite')
const csv = `果物,色,価格\nりんご,赤,300\nバナナ,黄,100` // CSVの内容を指定。 ,は列の区切りを示し、\nは改行です
const dist = path.join( process.env.PWD || process.cwd() , "書き出されたCSVファイル.csv") // 書き出すファイルのパス

// Shift-jisで書き出しする
fs.writeFileSync( dist , "" ) // 空のファイルを書き出す
let fd = fs.openSync( dist, "w") // ファイルを書き込み専用モードで開く
let buf = iconv.encode( csv , "Shift_JIS" ) // 書き出すデータをShift_JISに変換して、バッファとして書き出す
fs.write( fd , buf , 0 , buf.length , (err, written, buffer) => { // バッファをファイルに書き込む
if(err){
throw err
}
else {
console.log("ファイルが正常に書き出しされました")
}
})

最後にnode.jsを実行します。

bash
1
2
$ node csv.js
(同階層にCSVファイルが書き出される)

TSVをnode.jsを使って書き出す(UTF-16LE)

続いて、TSVをnode.jsで書き出す簡単なサンプルコードを載せてみたいと思います。まずはiconv-liteをnpmインストールします。

bash
1
2
$ npm init
$ npm install iconv-lite --save

続いて、node.jsのコードを作成し、以下のように記述します。

bash
1
$ vim tsv.js

注目したいポイントは、下記のコードのようにiconv.encode()メソッドで"UTF-16LE" , { addBOM: true }を指定することです。これにより、リトルエンディアンのUTF-16 BOM付きでバッファを得ることができます。

tsv.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 以下はES6で記述されており、node.js v8で動作します。
const fs = require('fs')
const path = require('path')
const iconv = require('iconv-lite')
const tsv = `果物\t色\t価格\nりんご\t赤\t300\nバナナ\t黄\t100` // CSVの内容を指定。 \tは列の句切れを示すタブ、\nは改行です
const dist = path.join( process.env.PWD || process.cwd() , "書き出されたCSVファイル.csv") // 書き出すファイルのパス

// Shift-jisで書き出しする
fs.writeFileSync( dist , "" ) // 空のファイルを書き出す
let fd = fs.openSync( dist, "w") // ファイルを書き込み専用モードで開く
let buf = iconv.encode( tsv , "UTF-16LE" , { addBOM: true } ) // 書き出すデータをUTF-16リトルエンディアンBOM付きに変換して、バッファとして書き出す
fs.write( fd , buf , 0 , buf.length , (err, written, buffer) => { // バッファをファイルに書き込む
if(err){
throw err
}
else {
console.log("ファイルが正常に書き出しされました")
}
})

最後にnode.jsを実行します。

bash
1
2
$ node tsv.js
(同階層にTSVファイルが書き出される)

まとめ

node.jsでExcelで開くことのできるCSVファイルやTSVファイルを、文字化けすることなく書き込む方法を解説しました。iconv-liteなどの変換モジュールを利用すると、様々な形式に対応した文字セットで書き込むことができます。