Laravel6.x, Laravel 5.8, 5.7で動作確認を行っています。

Laravel上でEXCELファイルをExport/ImportするためのパッケージLaravel Excelの使用方法について説明を行なっています。本文書を読み終えるとテーブルに保存されているデータをEXCELファイルでダウンロード、または保存することができます。さらにEXCELファイルに保存しているデータを一括でテーブルに保存することができます。

Laravel Excelのインストール

Laravel Excelを使用するためにComposerを利用してmaatwebsite/excelのインストールを行います。


$ composer require maatwebsite/excel

Composerがわからない人は下記の文書がおすすめです。

インストールすると下記のパッケージがインストールされます。


laravel $ composer require maatwebsite/excel
Using version ^3.1 for maatwebsite/excel
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 4 installs, 0 updates, 0 removals
  - Installing markbaker/matrix (1.1.4): Downloading (100%)         
  - Installing markbaker/complex (1.4.7): Downloading (100%)         
  - Installing phpoffice/phpspreadsheet (1.8.2): Downloading (100%)         
  - Installing maatwebsite/excel (3.1.15): Downloading (100%)
maatwebsite/excelはversion2から3にアップして、マニュアルや操作方法も変更になっているので注意が必要です。本文章ではversion3について説明を行います。

Exportファイルの作成

Laravel Exportを使用してExcelファイルを作成する場合はLaravel ExportのExportクラスを利用します。

Export用のクラスはphp artisan make:exportコマンドで作成することができます。

php artisan make:exportコマンドはLaravel Exportパッケージをインストールすることで実行できるコマンドです。つまりLaravel Export専用のartisanコマンドです。

usersテーブルに入ったデータをExportしてExcelファイルの作成を行うためmodelオプションでUserを指定して、ファイル名はUsersExportとします。


$ php artisan make:export UsersExport --model=User
Export created successfully.

appフォルダの下にExport/UsersExport.phpが作成されます。作成したUsersExport.phpにはcollectionメソッドが記述されています。


<?php

namespace App\Exports;

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

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

テーブルからのデータ取得部分をUserExportとしてわけることで、取得したいデータが変わった場合は、collectionメソッドの中身を変えるだけで対応することができます。

php artsain make:exportコマンドでmodelオプションを設定しなかった場合は、user App\Userとreturn User::all()が記述されていない状態で作成されます。

usersテーブルに入っているデータをExportしたいので、必ずusersテーブルへのデータ挿入を完了させておいてください。

動作確認のためにusersテーブルへのテストデータの挿入する際はSeeding機能を使うことをおすすめします。

usersテーブルにデータが挿入されているか確認するためにphp artisan tinkerを実行します。


 $ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.23 — cli) by Justin Hileman
>>> $users = App\User::all();
=> Illuminate\Database\Eloquent\Collection {#3003
     all: [
       App\User {#3004
         id: "1",
         name: "Vilma Bednar",
         email: "ioreilly@example.com",
         email_verified_at: "2019-07-30 01:29:27",
         created_at: "2019-07-30 01:29:27",
         updated_at: "2019-07-30 01:29:27",
       },

usersテーブルデータのExport

Excelファイルのダウンロード

Exportを実行するコントローラーの作成を行なってください。ここでは、UsersControllerを作成します。


$ php artisan make:controller UsersController 
Controller created successfully.

web.phpファイルに作成したUsersControllerコントローラーのルーティングを追加します。


Route::get('/', function () {
    return view('welcome');
});

Route::get('users','UsersController@export');

UsersControllerコントローラーにexportメソッドを記述します。


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel; 
use App\Exports\UsersExport; 

class UsersController extends Controller
{
    
    public function export(){

	    return Excel::download(new UsersExport, 'users.xlsx'); 

    }
    
}

ここまでのExport設定が完了したら、ブラウザを使用して、/usersにアクセスします。アクセスするとusers.xlsxファイルがダウンロードフォルダに保存されます。

users.xlsxファイルを開くとUsersテーブルに保存されているすべての行が保存されています。

ダウンロードしたEXCELファイルを開く
ダウンロードしたEXCELファイルを開く

EXCELファイルのヘッダー設定

ダウンロードしたEXCELファイルには、列名が表示されていませんでした。下記の設定を行い、ヘッダーを表示させます。headingsメソッドだけではなく、WithHeadingsインターフェイスを忘れずに追加してください。


use App\User;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;

class UsersExport implements FromCollection,WithHeadings
{
    /**
    * @return \Illuminate\Support\Collection
    */
    public function collection()
    {
        return User::all();
    }

	public function headings():array
	{
		return [
				'#', 
				'name', 
				'email', 
				'email_verified_at', 
				'created_at', 
				'updated_at'
			]; 
	}
}

ダウンロードしたファイルを開くと設定した列名が表示されます。

列名が記述されたEXCEL
列名が記述されたEXCEL
列名に日本語を使用することができます。また実際の列とheadingsの列名の数が一致しない場合はエラーにならず、不足した列名は空白で作成されます。

シートに名前をつける

デフォルではExcelのシートの名前はWorksheetになっていますが、シート名を任意の名前に変更することができます。

シート名を変更するためには、UsersExport.phpファイルにWithTitleインターフェイスを追加します。WithTitleを追加した後にtitleメソッドを追加し、シート名は指定すればシート名を指定した文字列に変更することができます。下記ではシート名はtestで作成されます。


namespace App\Exports;

use App\User;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithTitle;

class UsersExport implements FromCollection, WithTitle
{

	public function collection()
	{

	    return User::all();
	}

	public function title(): string{

		return 'test';

	}

}

ダウンロードする列を指定

UsersExport.phpファイルのcollectionメソッドではUser::all()を指定していたためすべての列情報が表示されました。


public function collection()
{
    return User::select('id','name','email')->get();
}

usersテーブルの中のidとnameとemailのみを取得することができます。collectionメソッドの内容を書き換えるだけで取得できるデータを変更することができるため、他のプログラムへの影響を最小限に留めることができます。

EXCEL以外のフォーマット保存

Laravel Excelという名前ですが、csvなどExcel以外のフォーマットにも対応しています。対応しているフォーマットはMaatwebsite\Excel\Excel.phpに記述されています。


class Excel implements Exporter, Importer
{
    use RegistersCustomConcerns;

    const XLSX     = 'Xlsx';

    const CSV      = 'Csv';

    const TSV      = 'Csv';

    const ODS      = 'Ods';

    const XLS      = 'Xls';

    const SLK      = 'Slk';

    const XML      = 'Xml';

    const GNUMERIC = 'Gnumeric';

    const HTML     = 'Html';

    const MPDF     = 'Mpdf';

    const DOMPDF   = 'Dompdf';

    const TCPDF    = 'Tcpdf';

下記のようにExcel::CSVを指定してダウンロードを行うとカンマ区切りのcsvファイルとして作成することができます。


public function export(){

    return Excel::download(new UsersExport, 'users.csv', \Maatwebsite\Excel\Excel::CSV); 

}

ダウンロードするフォーマットを指定しましたが、ファイルの拡張子を変更するだけで自動でダウンロードするフォーマットを変更してくれます。


public function export(){

    return Excel::download(new UsersExport, 'users.csv'); 

}

htmlファイルとして保存することができ、テーブル要素の中にデータを保存します。ファイル内でCSSが適用されているため、あまりきれいには表示されませんが、CSSを変更することで表示は簡単に変更することができます。

htmlファイルでダウンロード
htmlファイルでダウンロード

Exportableトレイト

ここまでの処理はExcel::downloadを使っていましたがExportableトレイトを使うと実行するコードを下記のように変更することができます。


public function export(){

    return (new UsersExport)->download('test.xlsx');

}

ExportableトレイトはUsersExport.phpファイルで下記のように記述します。


namespace App\Exports;

use App\User;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;

class UsersExport implements FromCollection
{
    use Exportable;

	public function collection()
	{

	    return User::all();
	}

}

複数シートのExcel作成

Laravel Excelを利用すると複数シートのExcelファイルの作成も簡単に行うことができます。

複数のシートを作成するためには、WithMultipleSheetsインターフェイスとsheetsメソッドが必要になります。1シートの場合はUsersExport.phpの中でcollectionメソッドを利用してデータを取得していましたが、複数シートの場合は、データを取得する別のクラスをsheetsメソッドの中で呼び出します。

forを使って1から10までの数字をUsersSheetクラスの中に挿入しています。


namespace App\Exports;

use Maatwebsite\Excel\Concerns\WithMultipleSheets;

class UsersExport implements WithMultipleSheets
{

	public function sheets(): array{

		$sheets = [];

		for($i = 1; $i <= 10; $i++){

			$sheets[] = new UsersSheet($i);

		}

		return $sheets;

	}

}

UsersSheetクラスはUsersExportを複製して下記のように作成します。今回はインスタンス化の際に$idを受け取り、その値を元に検索を行っています。


namespace App\Exports;

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

class UsersSheet implements FromCollection
{

	protected $id;

	public function __construct($id){

		$this->id = $id;

	}

	public function collection()
	{

	    return User::where('id',$this->id)->get();
	}

}

UsersControllerはこれまで通り、UsersExportを指定しています。


public function export(){
 
    return Excel::download(new UsersExport, 'test.xlsx'); 

}

ダウンロードを行うとtest.xlsxの中には10シートが作成され、それぞれのシートに1ユーザのみの行が挿入されています。

複数のシートを作成
複数のシートを作成

ここでは動作確認のために実行したこともあり、1シートに1ユーザの情報を取り出してExcelファイルを作成しました。複数のモデルのデータを別シートで取得したい場合は、UsersSheet.php以外にPostsSheetやInvoicesSheetを追加することで実現可能です。

サーバ上への保存する

アップロードしたファイルの保存方法について確認します。ダウンロードする際は、downloadメソッドを利用しましたが、ディスクに保存する場合は、storeメソッドを利用します。保存される場所は、Laravelインストールディレクトリのstorage/appの下に保存されます。


Excel::store(new UsersExport, 'users.xlsx');

storage/appディレクトリの下にあるpublicに保存する場合は、下記のように変更することで行うことができます。


Excel::store(new UsersExport, 'public/users.xlsx');

Importファイルの作成

本文書ではusersテーブルにデータをImportするためUserモデル用のImportファイルの作成を行います。


$php artisan make:import UsersImport --model=User
Import created successfully.

appフォルダの下にImport/UsersImport.phpが作成されます。作成したUsersImport.phpには、アップロードするEXCELファイルの列がインポートするテーブルのどの列に対応するのかを記述していきます。


namespace App\Imports;

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

class UsersImport implements ToModel
{
    /**
    * @param array $row
    *
    * @return \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new User([
            //
        ]);
    }
}

インポートしたいデータが保存されたEXCELファイルを確認します。A列には名前、B列にはEmail、C列にはパスワードが入っています。

Importを行うEXCELファイル
Importを行うEXCELファイル

この列情報を元にUsersImport.phpを更新します。

usersテーブルnameには0列、emailには1列、passwordは暗号化を行うので、Hashを使って列2を暗号化しています。

列番号は左から順番に0から番号が振られます。

    public function model(array $row)
    {
        return new User([
            'name' => $row[0],
            'email' => $row[1],
            'password' => Hash::make($row[2])
        ]);
    }

usersテーブルへのImport

web.phpにusersテーブルへのImportに必要なルーティングを追加します。


Route::resource('/users','UsersController');

UsersControllerのではファイルをアップロードするフォームを表示するindexメソッドとアップロードしたファイルをImportするstoreメソッドを記述しています。


namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Maatwebsite\Excel\Facades\Excel;
use App\Imports\UsersImport;

class UsersController extends Controller
{

    public function index(){

    	return view('index');

    }

    public function store(Request $request){

		$file = $request->file('file');

		Excel::import(new UsersImport, $file);

    }
}

resources¥viewsディレクトリの下にindex.blade.phpファイルを作成します。


<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>

	<form method="POST" action="/users" enctype="multipart/form-data">

		{{ csrf_field() }}

	<input type="file" id="file" name="file" class="form-control">

	<button type="submit">アップロード</button>

	</form>

</body>
</html>

/usersにブラウザからアクセスするとファイルをアップロードするため画面が表示されます。

Importファイルアップデート画面
Importファイルアップデート画面

ファイルには下記の内容が記述されたEXCELファイルをアップロードします。

Importを行うEXCELファイル
Importを行うEXCELファイル

実行後、php artisan tinker等を使用して、usersテーブルの行の情報を確認するとImportした2行の情報が追加されていることを確認することができます。


       App\User {#2966
         id: "11",
         name: "John Dow",
         email: "john.dow@example.com",
         email_verified_at: null,
         created_at: "2018-12-31 12:13:38",
         updated_at: "2018-12-31 12:13:38",
       },
       App\User {#2967
         id: "12",
         name: "Bill Gate",
         email: "bill.gate@example.com",
         email_verified_at: null,
         created_at: "2018-12-31 12:13:39",
         updated_at: "2018-12-31 12:13:39",
       },

Export, Importの日本語について

ImportするEXCELファイルに日本語を使用しても文字化けなしでImportすることができます。また、日本語で登録した情報をEXCELファイルでダウンロードすると文字化けなしで行うことができます。