◀ 4.

ERROR: Call to undefined method Maatwebsite\Excel\Excel::loa

▶
この記事の要点
  • Laravel Excel(maatwebsite/excel)3.x 系では Excel::load() と Excel::create() が廃止された
  • 2.x 系の解説記事のコードを 3.x 環境で動かすとこのエラーになる
  • 対処の基本は 3.1 の API に書き換えること: Excel::import() / Excel::toArray() / Excel::toCollection()
  • 2.x へのダウングレードは古い Laravel(5.x)専用。現行の Laravel では選べない
  • インストール済みのバージョンは composer show maatwebsite/excel で確認できる

エラー内容

Laravel で Excel / CSV ファイルを読み込もうとすると、ログ(storage/logs/laravel.log)に次のエラーが出ます。

local.ERROR: Call to undefined method Maatwebsite\Excel\Excel::load()

「Maatwebsite\Excel\Excel クラスに load() というメソッドは存在しない」という意味です。

原因: パッケージのバージョンと API の不一致

Laravel Excel は 2018 年の 3.0 で設計が大きく変わり、2.x 系で使われていた次のメソッドが削除されました。

  • Excel::load() … ファイルの読み込み
  • Excel::create() … ファイルの作成・出力
  • Excel::selectSheets() などのリーダー操作系

3.0 の時点では読み込み(インポート)機能自体が未提供で、インポートは 3.1(2018 年秋)で新しい API として復活しました。現在 composer require maatwebsite/excel を実行すると 3.1 系が入るため、ネット上に多い 2.x 時代のサンプル(Excel::load($path, function ($reader) { ... }))をそのまま使うと、このエラーになります。

まず、インストールされているバージョンを確認しましょう。

composer show maatwebsite/excel

versions : * 3.1.x のように表示されれば 3.1 系です。

対処法 1: 3.1 の API に書き換える(推奨)

旧コード(2.x)

Excel::load($path, function ($reader) {
    $rows = $reader->get();
    foreach ($rows as $row) {
        // $row->name などで列にアクセス
    }
});

新コード(3.1): 配列やコレクションとして読むだけの場合

中身を取り出して自分で処理したいだけなら、Import クラスを最小限で作り toArray() または toCollection() を使うのが一番簡単です。

php artisan make:import UsersImport
// app/Imports/UsersImport.php
namespace App\Imports;

use Maatwebsite\Excel\Concerns\WithHeadingRow;

class UsersImport implements WithHeadingRow
{
    // 1 行目を見出しとして扱い、列名をキーにする
}
use App\Imports\UsersImport;
use Maatwebsite\Excel\Facades\Excel;

// シートごとの配列が返る。[0] が 1 枚目のシート
$sheets = Excel::toArray(new UsersImport, $request->file('file'));

foreach ($sheets[0] as $row) {
    // $row['name'] のように見出し名でアクセス
}

新コード(3.1): そのまま DB に登録する場合

1 行を 1 モデルとして保存するなら ToModel を実装し、Excel::import() を呼びます。

namespace App\Imports;

use App\Models\User;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class UsersImport implements ToModel, WithHeadingRow
{
    public function model(array $row)
    {
        return new User([
            'name'  => $row['name'],
            'email' => $row['email'],
        ]);
    }
}
Excel::import(new UsersImport, $request->file('file'));

2.x と 3.1 の対応表

やりたいこと2.x3.1
読み込んで配列で受け取るExcel::load()->toArray()Excel::toArray(new XxxImport, $file)
読み込んでコレクションで受け取るExcel::load()->get()Excel::toCollection(new XxxImport, $file)
読み込んで DB に保存コールバック内で自前処理ToModel を実装して Excel::import()
1 行目を見出しにする設定ファイルの headingWithHeadingRow を実装
特定シートだけ読むselectSheets()WithMultipleSheets を実装
ファイルを作ってダウンロードExcel::create()->download()Export クラス+ Excel::download()

対処法 2: 2.x にダウングレードする(古い Laravel のみ)

既存の大量のコードを書き換えられない場合、2.1 系に戻す方法もあります。

composer require "maatwebsite/excel:~2.1.0"

ただし 2.1 系は Laravel 5 系の時代のパッケージで、すでに保守されていません。Laravel 6 以降では依存関係の制約でインストールできないことが多く、PHP の新しいバージョンでも動作しません。新規開発や Laravel のアップグレードを予定しているプロジェクトでは選ばないでください。

落とし穴

  • Facade の名前空間: 3.1 では use Maatwebsite\Excel\Facades\Excel; を使います。エラーメッセージにある Maatwebsite\Excel\Excel はその裏側の本体クラスです
  • 見出しのキー: WithHeadingRow を使うと見出しはスラッグ化され、「User Name」は user_name のようなキーになります
  • CSV の文字コード: Excel で保存した Shift_JIS の CSV は文字化けします。設定ファイル(config/excel.php)の CSV 入力エンコーディングを指定するか、UTF-8 で保存し直します
  • 大きなファイル: 数万行以上は WithChunkReading で分割読み込みしないとメモリ不足になりやすいです

確認方法

  1. composer show maatwebsite/excel でバージョンが 3.1 系であることを確認
  2. コード中に Excel::load や Excel::create が残っていないか全文検索する
  3. 小さなテスト用ファイルで Excel::toArray() を実行し、dd() で中身を表示して確認

詳しい使い方は公式ドキュメント(https://docs.laravel-excel.com/)の 3.1 のページを参照してください。

関連

Post Share
子ページ

子ページはありません

同階層のページ
  1. Fatal error: Maximum execution time of 30 seconds exceeded in...
  2. Fatal error: Uncaught Error: Cannot use object of type stdClass as array in ...
  3. Warning: Use of undefined constant ... - assumed '...' (this will throw an Error)
  4. ERROR: Call to undefined method Maatwebsite\Excel\Excel::load()
  5. Maximum execution time of 30 seconds exceeded
  6. Your requirements could not be resolved to an installable set of packages. ... To enable extensions, verify that they are enabled in your .ini files:
  7. could not find driver
  8. the requested PHP extension mbstring is missing from your system.
  9. the requested PHP extension dom is missing from your system.
  10. A non well formed numeric value encountered
  11. Warning: Cannot modify header information - headers already sent by ...
  12. php_network_getaddresses: getaddrinfo failed: Name or service not known
  13. XMLWriter::openUri(): Unable to resolve file path
  14. Object of class stdClass could not be converted to string
  15. Class 'Google_Service_Youtube' not found