DB に入ってるデータを CSV に出力する場合、文字コードがUTF8でよければあっさりいけるんだけども、Shift_JIS で吐いてくださいとか言われると難易度があがってけっこうめんどくさかったのでメモ。
UTF8でも問題ない場合
なにも考えず node-csv で普通に吐いて res.download しましょう。 csv.adaltas.com
ちなみに node-csv 初めて使ったけど、0.4系とそれ以外では書き方が違うしめんどいのでぼくは0.3系を使った(個人の感想です)
Shift_JISで吐くけどダウンロードはさせなくてもよい場合
以下がすごく参考になるのでありがたく写経しましょう。 qiita.com
要は、CSV に吐き出すときに pipe で Iconv 挟んで出力するという感じのようです。
Shift_JISで吐いてさらにダウンロードさせる場合
上のやり方で最後に res.download させればいいと思っていたらうまくいかなかったって話。
理由としては、stream が投げる Event の close ではまだ Iconv の変換が終わっておらずファイルが close されていないため、そこで res.download させても変換前のファイルもしくは単に空のファイルが返るだけということ (もしかしたらぼくのやり方が悪いだけでちゃんとしたらうまくいくのかもしれない)
なので、pipe で渡さず普通に to に渡せば close ではちゃんとファイルが閉じられているので、そこで Iconv で変換してファイルに書き戻すというやり方をしたらうまくいった。
// CSV出力 csv().from(result).to(filename, { quoted: true }) .on('close', function(){ console.log('close'); // utf8からShift_JISに変換 var contents = fs.readFileSync(filename, { encoding: 'utf8' }); var iconv = new Iconv('UTF-8', 'Shift_JIS//TRANSLIT//IGNORE'); var sjiscontents = iconv.convert(contents); fs.writeFileSync(filename, sjiscontents, { encoding: null }); res.download(filename); }) .on('error', function(error){ console.log(error.message); });
結論
Shift_JISで吐くな