CSVダウンロード
LaravelでDBにある情報をCSVとしてダウンロードさせる。
そのときの検索結果に紐づくリストなのでCSVファイルとして保存しない。
app/routes.php
<?php
// CSVダウンロード
Route::get('/csv', function() {
$users = \User::where('type', '=', '1')->get(['name', 'birth_day'])->toArray();
$stream = fopen('php://output', 'w');
foreach ($users as $user) {
fputcsv($stream, $user);
}
$headers = array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename="users.csv"',
);
return Response::make('', 200, $headers);
});
素直にfputcsvを使うのが良いみたいだ。
【修正】文字コード変換
UTF-8のままだとエクセルで文字化けするのでSJIS-winに文字コードを変換。
php://outputだとrewind()、fseek()が使えずファイルポインタを先頭に戻せないのでphp://tempを使用。
app/routes.php
<?php
// CSVダウンロード
Route::get('/csv', function() {
$users = \User::where('type', '=', '1')->get(['name', 'birth_day'])->toArray();
$stream = fopen('php://temp', 'r+b');
foreach ($users as $user) {
fputcsv($stream, $user);
}
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="users.csv"',
);
return Response::make($csv, 200, $headers);
});
【修正】ヘッダー行追加。
app/routes.php
<?php
// CSVダウンロード
Route::get('/csv', function() {
$users = \User::where('type', '=', '1')->get(['name', 'birth_day'])->toArray();
$csvHeader = ['名前', '誕生日'];
array_unshift($users, $csvHeader);
$stream = fopen('php://temp', 'r+b');
foreach ($users as $user) {
fputcsv($stream, $user);
}
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="users.csv"',
);
return Response::make($csv, 200, $headers);
});
【修正】ファサード対応
CSVクラス
app/Lib/CSV.php
<?php namespace MyProject\Lib\CSV;
use Response;
class CSV
{
public function __construct()
{
}
/**
* CSVダウンロード
* @param array $list
* @param array $header
* @param string $filename
* @return \Illuminate\Http\Response
*/
public function download($list, $header, $filename)
{
if (count($header) > 0) {
array_unshift($list, $header);
}
$stream = fopen('php://temp', 'r+b');
foreach ($list 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=$filename",
);
return \Response::make($csv, 200, $headers);
}
}
サービスプロバイダー
app/Lib/CSVServiceProvider.php
<?php namespace MyProject\Lib\CSV;
use Illuminate\Support\ServiceProvider;
class CSVServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bindshared('csv', function()
{
return new CSV;
});
}
}
ファサード
app/Facades/CSV.php
<?php namespace MyProject\Facades;
use Illuminate\Support\Facades\Facade;
class CSV extends Facade
{
public static function getFacadeAccessor()
{
return 'csv';
}
}
オートロード更新。
composer dump-autoload
パス追記
app/config/app.php
'providers' => array(
……………………
'MyProject\CSV\CSVServiceProvider',// 追記
'aliases' => array(
……………………
'CSV' => 'MyProject\Facades\CSV',// 追記
コントローラー修正
app/routes.php
<?php
// CSVダウンロード
Route::get('/csv', function() {
$users = \User::where('type', '=', '1')->get(['name', 'birth_day'])->toArray();
$csvHeader = ['名前', '誕生日'];
return CSV::download($users, $csvHeader, 'user_list.csv');
});