PHP
CSV

PHPで連想配列を日本語エンコードしてCSV出力する

More than 3 years have passed since last update.

PHPでCSV出力する方法で検索すると、

以下のような添字配列が例に挙がっていることが多い。

$data = array(

array('佐藤', '東京都', '29歳'),
array('田中', '千葉県', '31歳'),
array('鈴木', '北海道', '54歳')
);

ただ実際は下のようにDBから取得した連想配列をCSVで出力するケースの方が多いと思う。今回少しハマったのでメモしておく。

$assoc_data = array(

array('name' => '佐藤', 'address' => '東京都', 'old' => '29歳'),
array('name' => '田中', 'address' => '千葉県', 'old' => '31歳'),
array('name' => '鈴木', 'address' => '北海道', 'old' => '54歳')
);


連想配列のデータをCSVで出力する

全体の構成としては以下の様なコードになる。


  1. 連想配列で受け取ったデータをヘッダーをキーとして値のみ取得して添字配列に変換


  2. 各行に相当する$assoc_row[$header_name]をmb_convert_variablesでSJIS-winに変換


  3. fputcsvでCSV形式に変換


  4. ブラウザから直接ダウンロードさせる


  $csv_header = array(

'name',
'address',
'old',
);

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=data.csv');

$stream = fopen('php://output', 'w');
fputcsv($stream, $csv_header);

foreach($assoc_data as $key => $assoc_row){
$numeric_row = array();
foreach ($csv_header as $header_name) {
mb_convert_variables('SJIS-win', 'UTF-8', $assoc_row[$header_name]);
$numeric_row[] = $assoc_row[$header_name];
}
fputcsv($stream, $numeric_row);
}

SJIS-winに変換しているのは、

UTF-8のままだとエクセルで読み込んだ時に、

文字化けしてしまうのと、(株)のような機種依存文字に対応するため

他のブログとか読んでると、

mb_convert_encording

で、配列をエンコードしているコードをよく見かけるけど、

この関数は対象が文字列なのでうまく動かないはず。

なので、mb_convert_variablesで配列ごとエンコードするようにしていている。

まだ文字列中に改行コード、カンマが含まれている場合のコードは書いていないので必要になった時に追記しようと思います。

後、♥マークの文字がまだどうしても「?」になってしまって

ちゃんとエンコード出来ない。。

誰か適切な文字コードをご存知の方がいたら教えていただけると幸いです!