LoginSignup
11
15

More than 5 years have passed since last update.

ExpressでShift-JISのCSVを返す

Last updated at Posted at 2016-05-18

ExpressでCSVをダウンロードさせてExcelで開かせようということになりました。

まずUTF-8な環境のNode.jsなのでUTF-8でどうにかできないかと思っていると、以下の記事でUTF-16LEのTSVのファイルの拡張子がcsvならエクセルで開けるとの情報を得ました。

Win/Mac どちらの Excel でも正しく開ける Unicode な csv の出力方法

UTF-16ならBufferで扱えるし、Shift-JISよりはいいじゃないかと思ったら、古いExcelでは文字化けしてしまいました。

苦悩の末Shift-JISのCSVを出力するかと思い、次の記事を参考にiconvで変換しようと試みました。

Node.js (Express) で伝統的な CSV を出力する

何か文字化けしてダメだったので、今回は上2つでダメな場合どうしたかというのをメモ書きして置こうと思います。

文字コード変換

node-iconvがなぜか文字を正常に変換してくれなかったので、Shift-JISに特化したモジュールを使うことにします。

narirou/jconv

インストールなどもこちらに従ってください。

Expressの記述

Expressでsend等でデータを返すとContent-Typeのcharsetがutf-8に必ず書き換わっているようなので、上の記事と同じくwrite等を使います。

jconvと組み合わせて次のようにしました。

また今回はExcelで開くことを考慮し、Excelで中のデータが必ず文字列として表示できるよう、="データ"という感じでデータをまとめます(普通のCSVにしたい場合は=を削ってください)。

const jconv = require( 'jconv' );

... 省略 ...

router.get('/path/to/download/csv', (req,res,next) => {
  const filename = '日本語を含むファイル名';

  // 日本語UTF-8のファイル名をダウンロードするファイル名として使う。
  res.setHeader( 'Content-disposition', 'attachment; filename*=UTF-8\'\'' + encodeURIComponent( filename + '.csv' ) );

  // Content-Typeをcsvにして文字コードもShift-JISにする。
  res.setHeader( 'Content-Type', 'text/csv; charset=Shift_JIS' );

  const data = [
    [ 'CSV', '', 'データ' ],
    [ 'まぁ', 'こんな', '感じで' ],
  ];

  const str = data.map( ( v ) => {
    // 普通のCSVにしたい場合は、ここの2個所の=を削る
    return '="' v.join( '",="' ) + '"';
  } ).join( "\r\n" );

  res.write( jconv.convert( str, 'UTF8', 'SJIS' ) );
  res.end();
});

これでめでたくShift-JISのCSVを入手できましたとさ。

終わりに

  • ふぁっきゅーExcel
  • Win/Macでのファイル読み込みくらい同じ挙動にしてくれ……orz
  • 後UTF-8とかでも読み込んでorz
11
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
15