Laravel5.8でTraitsを利用してCSVファイルダウンロード


目的:

報酬のCSVファイルをアップロード後、別途経理に渡す給与明細のCSVファイルをダウンロードする処理を実装

1. ルード設定

Route::any('/csv/account/download/{ym}/{kind}', 'Csv\PaymentController@account')->where('ym', '[0-9]{4}-[0-1]{1}[0-9]{1}');

2. Controllers

namespace App\Http\Controllers\Csv;

use App\Http\Traits\Csv;
use App\Models\CsvFile;
use App\Http\Controllers\Controller;

/**
 * Class PaymentController
 * @package App\Http\Controllers\Csv
 */
class PaymentController extends Controller
{
    use Csv;

    /**
     * CSVをダウンロード(経理用)
     *
     * @param $ym
     * @param $kind
     * @return mixed
     */
    public function account($ym, $kind) {

        // ファイル名
        $filename = $ym.TF_CSV_ACCOUNT_FILE_NAME;
        $file = Csv::createCsv($filename);

        // ヘッダー
        $header = TF_CSV_ACCOUNT_FILE_HEADER;
        Csv::write($file, $header);

        // リスト
        $rentalList = $this->twPayment->getRentalList($kind, $ym);
        foreach ($rentalList as $rental){
          $data = [
                $rental->user_id,
                $rental->l_name. $rental->f_name,
                $rental->bank_name,
                $rental->branch_name,
                $rental->branch_code,
                $rental->account_number,
                $rental->name_kana,
                $total,
            ];

            // 値を入れる
            Csv::write($file, $data);
        }

        // ファイルコンテンツ取得
        $response = file_get_contents($file);

        // ストリームに入れたら実ファイルは削除
        Csv::purge($filename);

        return response($response, 200)
            ->header('Content-Type', 'text/csv')
            ->header('Content-Disposition', 'attachment; filename='.$filename);
    }
}

3. Traits

namespace App\Http\Traits;

trait Csv {

    /**
     * CSVファイルを生成
     *
     * @param $filename
     * @return mixed
     */
    public static function createCsv($filename) {
        $csv_file_path = storage_path('app/'.$filename);
        $result = fopen($csv_file_path, 'w');
        if ($result === FALSE) {
            throw new Exception('CSVファイルの書き込みに失敗しました。');
        } else {
            fwrite($result, pack('C*',0xEF,0xBB,0xBF)); // BOM をつける
        }
        fclose($result);

        return $csv_file_path;
    }

    /**
     * CSVファイルに書き出す
     * @param $filepath
     * @param $records
     */
    public static function write($filepath, $records) {
        $result = fopen($filepath, 'a');

        // ファイルに書き出し
        fputcsv($result, $records);

        fclose($result);
    }


    /**
     * CSVファイルの削除
     *
     * @param $filename
     * @return mixed
     */
    public static function purge($filename) {
        return unlink(storage_path('app/'.$filename));
    }
}

4.BOM をつける

fwrite($result, pack('C*',0xEF,0xBB,0xBF));

BOMをつけることでUTF-8で出力してもExcelで読めるようになる。