LoginSignup
123
133

More than 5 years have passed since last update.

LaravelでCSVダウンロード。

Last updated at Posted at 2014-12-19

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');
});
123
133
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
123
133