集計データをcsvにエクスポートする処理をLaravel Excelを使って置き換える機会があったので備忘録としてまとめてみます。Laravel Excelとはcsvやxlsxファイルなどへのデータのエクスポート、インポートがお手軽に実現できるパッケージです。

公式ページに色々利点が列挙されていますが、今回の導入で期待しているのは以下の3点です。

1 データをxlsxファイルにエクスポート
2 chunk処理によるエクスポート処理のパフォーマンスアップ
3 整理整頓されたクラスセットによりコードの見通しがよくなる

まずはインストールから。

環境

  • macOS Big Sur バージョン 11.1
  • PHP 7.4.15
  • Laravel Framework 7.30.4

新規プロジェクトが作成されている状態

installation

公式ドキュメントに沿ってパッケージをインストールします。

予めRequirementsを確認し、PHPのextensionなど入っていないものが有れば必要に応じて入れて下さい。私の環境ではgdのみ入っていなかったので以下の手順で入れました。(phpbrewを使っています)

brew install gd
phpbrew ext install gd

それではLaravel Excelをインストールします。

composer require maatwebsite/excel

2021/02/24時点では3.1.27が入りました。

購入履歴をエクスポートしてみる

どのECサイトでも顧客動向を把握するために、商品の購入履歴を分析すると思います。マーケの人からそれに必要なデータをExcelで開ける形式で下さい、と依頼されたとしましょう。そんな時、従来であればBOMや文字コードを気にかけつつ、fputcsvなどでcsvファイルに出力していました。Laravel Excelを使えば直接xlsxファイルで出力できるので、それらの煩わしさから解放されそうです。

例えば以下のようなテーブルからデータをエクスポートするとします。

ダミーデータの準備

まずはモデルを作成、migartionファイルと後ほどダミーデータを生成するのでfactoryもオプションで指定して作成しておきます。

php artisan make:model -fm PurchaseHistory

migrationファイルは以下のようにしました。

public function up()
{
    Schema::create('purchase_histories', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->integer('user_id')->default(0);
        $table->string('product_name')->default('');
        $table->integer('price')->default(0);
        $table->smallInteger('quantity')->default(0);
    });
}

migrateします。

php artisan migrate

続いてfactory側も準備します。

$factory->define(PurchaseHistory::class, function (Faker $faker) {
    return [
        'user_id' => $faker->randomNumber(),
        'product_name' => $faker->word(),
        'price' => $faker->randomNumber(4),
        'quantity' => $faker->randomNumber(1),
    ];
});

tinkerから100レコードほどダミーデータを生成しておきます

factory('App\PurchaseHistory', 100)->create();
PurchaseHistory::count();
>> 100

これでダミーデータの準備完了です。

Exportクラスを作成

以下のコマンドでExportファイルを生成して下さい。

php artisan make:export PurchaseHistoryExport

app\Exports\PurchaseHistoryExport.php が生成されるはずです。このクラスでヘッダや、ソースからのデータ取得、出力データの整形などを指定していきます。デフォルトでcollectionメソッドが定義されていますので以下のように編集します。

namespace App\Exports;

use App\PurchaseHistory;
use Maatwebsite\Excel\Concerns\FromCollection;

class PurchaseHistoryExport implements FromCollection
{
    /**
    * @return \Illuminate\Support\Collection
    */
    public function collection()
    {
    	return PurchaseHistory::all();
    }
}

これでpurchase_historyテーブルから抽出したデータを全てエクスポートすることになります。試しにtinkerからエクスポートしてみます。

use App\Exports\PurchaseHistoryExport;
Excel::store(new PurchaseHistoryExport, 'purchase_history.xlsx');

第一引数に先程編集したExportクラス、第2引数に出力するファイル名を指定しています。trueが返されればエクスポート完了です。出力先はデフォルトでstorage/app/purchase_history.xlsxになります

お手軽ですね!因みにファイル名の拡張子を’xlsx’から’csv’にするとcsv形式でも出力してくれます。その他、対応している拡張子が公式ドキュメントの方に載っていますのでチェックしてみて下さい。

長くなってしまったので、続きは次の記事にします。

By hikaru