条件に該当するレコードをCSVで出力する
検索条件に該当するレコードを一括でCSV出力してダウンロードさせる方法について解説。
ライブラリ「Laravel-Excel」を使う。
今回は、Customers(顧客)テーブルのデータをダウンロードすることを想定して解説。
Laravel-Excelのインストールと設定ファイル生成
composer require maatwebsite/excel
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider"
クラスを作成
php artisan make:export CustomerExport
プロジェクトディレクトリ\app\Exports\CustomerExport.php
が生成される。
作ったクラスは後で編集する。
コントローラーからクラスを呼び出せるようにする
//プロジェクトディレクトリ\app\Http\Controllers\CustomerController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Customer;//モデル読み込み
use Carbon\Carbon;//日時取得
//csv関係
use App\Exports\CustomerExport;//追記
use Maatwebsite\Excel\Facades\Excel;//追記
use Maatwebsite\Excel\Validators\ValidationException;//追記
//中略
class CustomerController extends Controller
{
public function exportCustomerToCsv(Request $request){
//$request = {key:'あいうえお'}
return Excel::download(new CustomerExport($request), Carbon::now()->format('Y-m-d-h-m-s').'customers.csv');
}
}
メソッドexportCustomerToCsv()
が呼ばれたら 、
さっき作ったクラスCustomerExport
にリクエスト(検索条件)を渡す。
クラス内のにおける処理の実行結果を現在の日時.customer.csvと
いうファイル名で保存する
今回は、$request = {key:'あいうえお'}
が条件だったことにする。
CustomerExportクラスを編集
<?php
//プロジェクトディレクトリ\app\Exports\CustomerExport.php
namespace App\Exports;
use App\Models\Customer;//モデル名
use Illuminate\Support\Facades\Schema;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class CustomerExport implements FromCollection, WithHeadings, WithMapping
{
private $table = "customers";//テーブル名
private $columns;
private $searchCondition;//これから使いまわす変数を宣言
public function __construct($request)//コントローラーから(request)検索条件を受け取る
{
$this->searchCondition = $request;//コントローラーから受け取った検索条件をcollectionメソッドで呼び出せる様にする
$this->columns = Schema::getColumnListing($this->table);
}
/**
* @return \Illuminate\Support\Collection
*/
public function collection()
{
$searchCondition = $this->searchCondition;
$CustomerQuery = Customer::query();
if($searchCondition->key){
$key = '%' . addcslashes($searchCondition->key, '%_\\') . '%';//部分一致
$CustomerQuery->where(function ($query) use($key){
$query->where('answer','LIKE',$key);
});
}
return $CustomerQuery->orderBy('id', 'desc')->get();
}
public function headings(): array
{
return $this->columns;
}
public function map($row): array
{
$array = [];
$columns = $this->columns;
foreach ($columns as $column) {
$array[] = $row->{$column};
}
return $array;
}
}
コントローラーから送信したリクエスト(検索条件)は、まず __construct()
メソッドで受け取られる。
ややこしいけどここが結構重要。
__construct()
内で、リクエスト(検索条件)を他のメソッド内でも $this->searchCondition
という名称で呼び出せるように調整している。
で、今回の例だとcustomers
テーブルのanswer
カラムに「あいうえお」という文字列を含むレコードを全件取得して、
CSVでダウンロードさせることになる。
ちなみに条件に該当するレコードの全カラムが出力される。
一部だけに限定することもできるので、下記のサイトを参考にしてほしい
参考にしたサイト
どうやってメソッドを呼び出すん?
例えばAPIでメソッドを呼び出したいとする。
<?php
//api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;;
use App\Http\Controllers\CustomerController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get('/customers/export', [CustomerController::class, 'exportCustomerToCsv']);
あとは、aタグなどでリンクして下記のURLを呼び出せばダウンロードが始まる。
/api/customers/export?key=a
検索機能に付け加えるなら、aタグ内のリンクを必要に応じて動的に変化させればいい。
↓
<a :href="downloadUrl">CSVでダウンロード</a>
downloadUrl
の内容を動的に変化させるわけやな。
リンクをクリックしたらメソッドが発火していきなりダウンロードが始まる。