今どきPHPでシステムを組む場合、ほぼUTF-8で作ることになります。
UTF-8はSJISと違って文字化けの心配もなくて安心ですが、CSVファイルにする場合だけは勝手が違います。
PHPの文字コードがUTF-8のままCSVファイルを生成すると、エクセルで開いたときに日本語の部分が文字化けしてしまいます。
これはエクセルが強制的にSJISで開いているから起きているんです。
これでは、使い物にならないので、CSVを生成するときにひと手間加える必要があります。
今回は、日本語が入った配列データを文字化けせずにCSVファイルに保存する方法を紹介します。
[box class=”pink_box” title=”他の文字コードからSJISに変換する場合”]
UTF-8ではなく、ほかの文字コードからSJISに変換する場合は、UTF-8となっている部分を対象の文字コードに変換すればOKです。
[/box]
目次
日本語が入った配列データを文字化けせずにCSVファイルに保存する方法
今回は以下の配列データをCSVファイルに保存します。
$data = [ ['日本語', '文字化け対応', 'テスト'], ['日本語', '文字化け対応', 'テスト'], ];
stream_get_contentsを使う方法
stream_get_contentsを使う場合、以下のような関数を作ります。
/** * CSVを生成 * @param array CSVに変換する2次元配列 * @param string CSVの保存先 */ function create_csv($data, $save_path) { //一時データを開く $fp = fopen('php://temp', 'r+b'); //fputcsvでCSVデータを作る foreach ($data as $val) { fputcsv($fp, $val); } //ファイルポインタを先頭に戻す rewind($fp); //ストリームの中身をテキストデータに変換、 //さらにテキストデータをUTF-8からSJIS-winに変換する $str = str_replace(PHP_EOL, "\r\n", stream_get_contents($fp)); $str = mb_convert_encoding($str, 'SJIS-win', 'UTF-8'); //一時データのファイルポインタを閉じる fclose($fp); //CSVファイルを生成して、データを書き込んで保存する $fp2 = fopen($save_path, "w"); fwrite($fp2, $str); fclose($fp2); }
スクリプトはは長いですが、CSV用のデータを一括でUTF-8からSJIS-winに変換しています。
あとは以下のように実行すれば、CSVファイルが生成されます。
$data = [ ['日本語', '文字化け対応', 'テスト'], ['日本語', '文字化け対応', 'テスト'], ]; $save_path = "sample.csv"; create_csv($arrays,$save_path);
mb_convert_variablesを使う方法
mb_convert_variablesを使って、配列をつどUTF-8からSJIS-winに変換する場合は、以下のように関数を作ります。
あとは以下のように実行すれば、CSVファイルが生成されます。
/** * CSVを生成 * @param array CSVに変換する2次元配列 * @param string CSVの保存先 */ function create_csv($data, $save_path) { //保存するファイルのファイルポインタを開く $fp = fopen($save_path, "w"); //fputcsvでCSVデータを作る foreach ($data as $val) { mb_convert_variables('SJIS-win', 'UTF-8', $val); fputcsv($fp, $val); } //ファイルポインタを閉じる fclose($fp); }
mb_convert_variablesを1レコード単位で実行するため、レコード数が多いと速度に影響が出てきます。
$data = [ ['日本語', '文字化け対応', 'テスト'], ['日本語', '文字化け対応', 'テスト'], ]; $save_path = "sample.csv"; create_csv($arrays,$save_path);
コメント