今どき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);

コメント