やりたいこと
Controller内でデータを取得し、csvのレスポンスを生成して返すControllerを作成します。
どこかのストレージにすでに存在するcsvをレスポンスとして返すものとは少々異なります。
実装
モデル
扱うデータ用オブジェクトは下記のものします。
app\Models\Person.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
protected $table = 'persons';
protected $fillable = [
'name',
'age'
];
}
ルーティング
リクエストをControllerにつなぎこみます。
ここは普通にGETリクエストを行う場合と同じやり方。
routes/web.php
Route::get('/persons/download/csv', 'PersonController@download_csv');
コントローラー
ここでレスポンスでcsvを返す処理を書きます。
app\Http\Controllers\PersonController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Schema;
use App\Models\Person;
class PersonController extends Controller
{
public function download_csv(Request $request)
{
$persons = Person::all();
$persons = $persons->toArray();
// 全カラム名を配列で取得
$header = Schema::getColumnListing((new Person)->getTable());
// レスポンスストリームにcsv用のデータを書き込み
$stream = fopen('php://temp', 'r+b');
fputcsv($stream, $header);
foreach ($persons as $row) {
fputcsv($stream, $row);
}
rewind($stream);
$csv = str_replace(PHP_EOL, "\r\n", stream_get_contents($stream));
$csv = mb_convert_encoding($csv, 'SJIS-win', 'UTF-8');
$headers = array(
'Content-Type' => 'text/csv',
'Content-Disposition' => "attachment; filename=persons.csv", // ファイル名
);
return Response::make($csv, 200, $headers);
}
これで、 /persons/download/csv
にアクセスすれば、csvがダウンロードされます。