はじめに
実務で、CSVダウンロード機能の実装を行いましたので、備忘録として残します。
CSVダウンロード機能の実装
例として、ユーザー情報をCSVで出力するとします。
まず、実装コードとしては、以下になります。
後ほど、それぞれ解説いたします。
$users = User::get();
$csvHeader = [
'ID','姓','名','姓カナ','名カナ','メールアドレス','性別','生年月日','年齢'
];
$temps = [];
array_push($temps, $csvHeader);
foreach ($users as $user) {
$temp = [
$user->id,
$user->name1,
$user->name2,
$user->name_kana1,
$user->name_kana2,
$user->email,
$user->sex,
$user->age,
];
array_push($temps, $temp);
}
$stream = fopen('php://temp', 'r+b');
foreach ($temps as $temp) {
fputcsv($stream, $temp);
}
rewind($stream);
$csv = str_replace(PHP_EOL, "\r\n", stream_get_contents($stream));
$csv = mb_convert_encoding($csv, 'SJIS-win', 'UTF-8');
$now = new Carbon();
$filename = "ユーザー一覧(全件:" . $now->format('Y年m月d日'). ").csv";
$headers = array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename='.$filename,
);
return Response::make($csv, 200, $headers);
コードの解説
① CSVの項目名作成
$csvHeader = [
'ID','姓','名','姓カナ','名カナ','メールアドレス','性別','生年月日','年齢'
];
CSVの項目名を配列にしています。
② 出力したいデータの作成
$temps = [];
array_push($temps, $csvHeader);
出力したいデータを保存するため、$tempという配列を作成し、先ほど作成した項目名の配列を追加しています。
foreach ($users as $user) {
$temp = [
$user->id,
$user->name1,
$user->name2,
$user->name_kana1,
$user->name_kana2,
$user->email,
$user->sex,
$user->age,
];
array_push($temps, $temp);
}
また、出力するユーザー情報に関しても、foreachで取り出し、$tempに追加します。
③ 書き込み用のファイルを一時的に作成し、開く
$stream = fopen('php://temp', 'r+b');
書き込み用のファイルを開くために、fopen関数を使用します。
fopen関数とは
ファイルまたは URL をオープンする関数のこと。
第一引数にはファイル名、第二引数にはモードを指定します。
モードはいくつか種類があります。
参考URL: https://www.php.net/manual/ja/function.fopen.php
④ 作成したファイルに出力したいデータを書き込む
foreach ($temps as $temp) {
fputcsv($stream, $temp);
}
foreachで値を取り出し、fputcsv関数を使用して、ファイルにデータを書き込みます。
⑤ ファイルポインタを先頭に戻す
rewind($stream);
次に行う操作が、ファイルの先頭から始める必要があるため、rewind()を使用してファイルポインタを先頭に戻します。
⑥ 改行コードを置き換え・文字列に変換・エンコード
$csv = str_replace(PHP_EOL, "\r\n", stream_get_contents($stream));
fputcsvで書き込む際に、1つ書き込むたびに改行コード(PHP_EOL)が追加されています。
この改行コードがOS依存のため、str_replace関数を用いて「\r\n」に置き換えます。
また、stream_get_contents関数を用いて、文字列に変換します。
⑦ 文字列をエンコードする
$csv = mb_convert_encoding($csv, 'SJIS-win', 'UTF-8');
PHPは「UTF-8」で書かれているが、CSVをExcelで開く際に「sjis-win」で開き、文字化けを防ぐため、「sjis-win」にエンコードします。
⑧ ファイルをCSV形式に変換する
$headers = array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename='.$filename,
);
⑨ CSVファイルを出力する
return Response::make($csv, 200, $headers);
さいごに
実装する中で、色々な関数を使用したりして、とても勉強になりました!
この記事が皆さんの参考になりますと幸いです。
最後までお読みいただき、ありがとうございました!
(間違っているとこなどありましたら、ぜひご指摘ください!)