LaravelでCSVファイルとして出力(ダウンロード)する方法メモ。例として、View側で入力した年齢からユーザを取得し、CSVファイルとしてダウンロードする処理を紹介します。
View側の処理
Viewで入力した値をコントローラにsubmitします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ... {!! Form::open(['action' => 'UsersController@csv', 'method' => 'get', 'target' => '_blank']) !!} <div class="input-field"> {!! Form::number(‘age’, null, [ 'placeholder' => '半角数字で入力']) !!} <label class="age">年齢</label> </div> <input class="csv-download" type="submit" value="CSVダウンロード"> {!! Form::close() !!} ... |
ルーティング
コントローラにGETリクエストするためのルーティングを記述。
1 | Route::get('users/csv', 'UsersController@csv'); |
コントローラ
Viewから送られてきたリクエスト(ここで言う年齢)から、同年齢のユーザ情報取得します。ユーザ情報はサービスに送り、実際のCSVダウンロードの処理はサービスで行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ... private $csvService; /** * コンストラクタ * * @param App\Services\Users\CsvService $csvService * */ public function __construct(CsvService $csvService) { $this->csvService = $csvService; } /** * CSVダウンロード * * @param Request $request リクエスト * * @return csv */ public function csv(Request $request) { // リクエストで送られてきた年齢を取得 $target_age = $request->input('age'); // 同年齢のユーザ情報取得 $target_age_users = Users::where(‘age’, $target_age)->get(); // CSVダウンロード return $this->csvService->download($target_age_users, $target_age); } ... |
サービス
SymfonyのStreamedResponseクラスを使用し、CSVダウンロードを行います。StreamedResponseは大容量のCSVにも耐えることができます。
php://outputストリームを使用してファイルに書き出すことなく、CSV形式を都度出力します。
配列データをCSVファイルに書き込むfputcsv関数を使用し、CSV形式にフォーマットします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | <?php namespace App\Services\Users; use App\Services\Users\CsvService; use Symfony\Component\HttpFoundation\StreamedResponse; class CsvService { /** * ユーザ情報 CSVダウンロード * * @param array $target_age_users 同年齢のユーザ情報 * @param int $target_age 入力された年齢 * * @return StreamedResponse CSVファイル情報 */ public function download($target_age_users, $target_age) { // CSVファイル名 $current_time = now(); $file_name = $target_age.$current_time->format('YmdHis').'.csv'; $streamed_response = new StreamedResponse( function () use ($target_age_users) { $stream = fopen('php://output', 'w'); fputcsv($stream, [ mb_convert_encoding('ユーザID', 'SJIS', 'auto'), mb_convert_encoding('ユーザ名', 'SJIS', 'auto'), mb_convert_encoding('郵便番号', 'SJIS', 'auto'), mb_convert_encoding('住所', 'SJIS', 'auto'), mb_convert_encoding('電話番号', 'SJIS', 'auto'), ]); if (isset($target_age_users)) { foreach ($target_age_users as $target_age_user) { fputcsv($stream, [ mb_convert_encoding($target_age_user['id'], 'SJIS', 'auto'), mb_convert_encoding($target_age_user['name'], 'SJIS', 'auto'), mb_convert_encoding($target_age_user['postal_code'], 'SJIS', 'auto'), mb_convert_encoding($target_age_user['address'], 'SJIS', 'auto'), mb_convert_encoding($target_age_user['tel'], 'SJIS', 'auto'), ]); } } fclose($stream); }, \Illuminate\Http\Response::HTTP_OK, [ 'Content-Type' => 'text/csv', 'Content-Disposition' => 'attachment; filename=$file_name', ] ); return $streamed_response; } } |
以上、LaravelでCSVファイルとして出力(ダウンロード)する方法でした。