こんにちは、ごみばこです。
CSV ファイルってデフォルトでエクセルを使って開けるんですけど、どうにも文字コードを上手いことしてあげないとだめなんですよね。ということで幾つかの組み合わせについてぐぐったり、試したり、調べたのでメモ程度にー。
(ぐぐったらいろんな人が書いていて今更感もありますが・・・)
試したコードはこちら
<?php
// http://php.net/manual/ja/mbstring.supported-encodings.php
$encoding = [
'UTF-8',
'UTF-16BE',
'UTF-16LE',
'UTF-32BE',
'UTF-32LE',
'EUC-JP',
'SJIS',
'SJIS-win',
'ISO-2022-JP',
'CP932',
];
// https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF
$bom = [
'UTF-8' => chr(0xEF) . chr(0xBB) . chr(0xBF),
'UTF-16BE' => chr(0xFE) . chr(0xFF),
'UTF-16LE' => chr(0xFF) . chr(0xFE),
'UTF-32BE' => chr(0x00) . chr(0x00) . chr(0xFE) . chr(0xFF),
'UTF-32LE' => chr(0xFF) . chr(0xFE) . chr(0x00) . chr(0x00),
];
$ary = ['abcdef', 'テスト', 'ほげほげ', '??'];
ob_start();
echo '"' . implode('","', $ary) . '"'; // とりあえず雑に...
$buf = ob_get_flush();
// bom なし
foreach($encoding as $e) {
file_put_contents("{$e}.csv", mb_convert_encoding($buf, $e));
}
// bomあり版
foreach($encoding as $e) {
if (empty($bom[$e])) {
continue;
}
file_put_contents("{$e}_bom.csv", $bom[$e] . mb_convert_encoding($buf, $e));
}
寿司ビールが正しく出れば Unicode も適切に処理されているはずなので安心安全ですね!
では結果を順番に見ていきましょう。
まとめるとこんな感じですね!
- CP932 や SJIS, EUC-JP などでは案の定、寿司ビールは出ません。
- UTF では BOM ありでないと文字化けしてしまいました。
- UTF-16 では LE にする必要がありました。
- UTF-16 では他のものと異なり、自動でカンマ部分の解釈がされないようでした。
- UTF-32 はダメです。
というわけで、とりあえず UTF-8 BOM あり にしておけば、色々と安心安全に動くんじゃないかなーと思います。
または、どうしても表でほしいなら xlsx を直にいじくりまわす、ですかねー。
PHP なら phpexcel 。Java なら POI 。Python なら xlrd + pandas 。
などと様々な言語から xlsx を利用する手立てがあります(あたまの良い人ありがとう)ので、これらを使っていくことも検討すべきかと思います。まあ、つらいところもあるので、難しいものなら、そもそもいる?、なんて話にした方がいいよいかもしれませんね!