Export Excel using maatwebsite/excel in Laravel 5.8

Export Excel using maatwebsite/excel in Laravel 5.8

Trong các project admin quản lý ta thường có các chức năng thêm, sửa, xóa, import excel, export excel,...và nhiều chức năng khác
Nay mình chia sẻ với mọi người mình dùng thử, thư viện maatwebsite/excel như thế nào nhé, ở đây mình dùng maatwebsite/excel 3.1 mới nhất nhé
Đầu tiên ta cần cài đặt maatwebsite/excel

# composer require maatwebsite/excel

Maatwebsite\Excel\ExcelServiceProvider sẽ được đăng ký mặc định vào config/app.php cho ta, hoặc mọi người có thể đăng ký trong file config/app.php như sau

'providers' => [
    /*
     * Package Service Providers...
     */
    Maatwebsite\Excel\ExcelServiceProvider::class,
]
'aliases' => [
    ...
    'Excel' => Maatwebsite\Excel\Facades\Excel::class,
]

Sau khi chỉnh xong chạy câu lệnh bên dưới để thực thi

php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider"

Với câu lệnh chạy bên trên sẽ tạo ra một file excel.php trong config/excel.php 
Trong bài này mình đã chuẩn bị sẵn các chức năng như sau, các bạn có thể nhìn thấy trong hình bên dưới đây

+ Exporting collections

- Bạn chạy câu lệnh bên dưới, mình tạo một file tên là UsersExport hoặc các bạn có thể tạo PostsExport theo table của các bạn để có thể dễ nhận biết hơn 

php artisan make:export UsersExport --model=User

- Sau khi chạy câu lệnh bên trên, sẽ tạo cho ta file UsersExport.php trong App\Exports\UserExport.php 

namespace App\Exports;

use App\User;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class UsersExport implements FromCollection,WithHeadings,WithMapping
{
    /**
    * @return \Illuminate\Support\Collection
    */
    public function collection()
    {
        return User::all();
      
    } 
    /**
     * Returns headers for report
     * @return array
     */
    public function headings(): array {
        return [
            'ID',
            'Name',
            'Email',     
            "Created",
            "Updated"
           
        ];
    }

    public function map($user): array {
        return [
            $user->id,
            $user->name,
            $user->email,
            $user->created_at,
            $user->updated_at
        ];
    }
}

- File bên trên mình use App\User để sử dụng Eloquent trong Laravel, đồng thời mình dùng class của Maatwebsite\Excel để ta có thể sử dụng chức năng export
- Hàm headings(): ta định nghĩa các cột title trong file excel khi export ra
- Hàm Map($user): ta chỉ định giá trị cần show ra, tương ứng với heading ta đã cài đặt 
- Tiếp theo ta sẽ cài đặt ở file Controller để có thể sử dụng file UsersExport.php, use App\UsersExport đển UserController.php

use App\Exports\UsersExport;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Controllers\Controller;

class UsersController extends Controller 
{
    public function export(Request $request) 
    {
        $type = $request->type;
        return Excel::download(new UsersExport, 'users.'.$type);
    }
}

- Bên trên mình có get params trên Url được type. Type chính là kiểu Export, có thể là (xlsx,csv,tsv) ta có thể chèn vào động để dễ dàng sử dụng chúng

+ Exportables

- Tiếp mình dùng ExportTables, ở đây mình vào thư mục App\Exports tạo file UsersExportQuyery.php hoặc bạn có thể chạy câu lệnh dưới đây

php artisan make:export UsersExportQuyery --model=User

- Trong file UsersExportQuyery mình cấu hình như sau:

namespace App\Exports;
use App\User;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;

class UsersExportQuery implements FromQuery
{
    use Exportable;

    public function __construct(int $year,$created_at)
    {
        $this->year = $year;
        $this->created_at = $created_at;
    }

    public function query()
    {
        //return User::query()->whereYear('created_at', $this->year);
        return User::query()->whereDate('created_at',$this->created_at);
    }
}

- Code bên trên mình chèn tham số(year,created) để có thể export theo year(năm),created(ngày tạo) của ta trong CSDL.
- Các giá trị được chèn bên trên được chèn từ UserController.php gọi đến UsersExportQuery.php 
- Giờ ta mở file UserController.php chỉnh sửa lại như sau:

use App\Exportes\UsersExportQuery;
public function export(Request $request) 
    {
        $type = $request->type;
       
        if($request->created!="" && $request->template==""){
            $now = new Carbon($request->created);
            $year = $now->year;
            $created = $request->created;
            return Excel::download(new UsersExportQuery($year,$created),'users.'.$type);
        }
        return Excel::download(new UsersExport, 'users.'.$type);
    }

- Trong đoạn code bên trên mình kiểm tra nếu người dùng có chọn ngày thì sẽ gọi đến UserExportQuery($year,$created)

+ From View

- Tiếp tục ta tạo file UsersExportView.php và cấu hình như sau:

namespace App\Exports;

use App\User;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\WithDrawings;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;

class UsersExportView implements FromView,WithDrawings
{
    public function __construct($template){
        $this->template = $template;
    }
    public function drawings()
    {
        $drawing = new Drawing();
        $drawing->setName('Logo');
        $drawing->setDescription('Hoanguyenit');
        $drawing->setPath(public_path('/img/logo.png'));
        $drawing->setHeight(90);
        $drawing->setCoordinates('F3');

        return $drawing;
    }
    public function view(): View
    {
       
        return View($this->template)->with(array('users' => User::all()));
    }
}

- Trong đoạn code bên trên mình có 2 function:view() & drawings(), trong view() ta return về template trong thư mục views ta cần hiển thị, còn drawings() ta dùng chèn hình ảnh vào một column trong excel của ta cần
- Trong From View này, bạn cần tạo một file trong thư mục Views, ví dụ ta tạo file template-export-excel.blade.php trong thư mục Views

<table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Email</th>
                <th>Created</th>
                <th>Updated</th>
            </tr>
        </thead>
        <tbody>
        @foreach($users as $user)
            <tr>
                <td>{{$user->id}}</td>
                <td>{{$user->name}}</td>
                <td>{{$user->email}}</td>
                <td>{{$user->created_at}}</td>
                <td>{{$user->updated_at}}</td>
            </tr>
        @endforeach
        </tbody>
    </table>

- Ta chỉnh sửa lại function export trong file UserController.php của ta lại như sau:

public function export(Request $request) 
    {
        $type = $request->type;
       
        if($request->created!="" && $request->template==""){
            $now = new Carbon($request->created);
            $year = $now->year;
            $created = $request->created;
            return Excel::download(new UsersExportQuery($year,$created),'users.'.$type);
        }else if($request->created=="" && $request->template!=""){

            return Excel::download(new UsersExportView($request->template), 'users.'.$type);
        }
        return Excel::download(new UsersExport, 'users.'.$type);
    }

- Vậy là ta đã cài đặt xong, để hiện thị được như hình bên trên mình giới thiệu ở đầu bài, mình tạo file list-users.blade.php trong views/list-users.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            
            <a href="{{route('export',['1','type'=>'xlsx'])}}" class="btn btn-success">Export Excel</a>
            <a href="{{route('export',['1','type'=>'csv'])}}" class="btn btn-info">Export CSV</a>
            <a href="{{route('export',['1','type'=>'tsv'])}}" class="btn btn-warning">Export TSV</a>
        
            
            <div class="btn-group">
                    <button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                           Export Query theo ngày
                    </button>
                    <div class="dropdown-menu">
                        @foreach($users as $user)
                                <a href="{{route('export',['1','type'=>'xlsx','created'=>$user->created_at->format('Y-m-d')])}}" class="dropdown-item">
                                       {{$user->created_at->format('Y-m-d')}} 
                                </a>
                        @endforeach
                           
                    </div>
            </div>
            <a href="{{route('export',['1','type'=>'xlsx','template'=>'template-export-excel'])}}" class="btn btn-warning">Export Excel to View</a>
            <table class="table">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Name</th>
                        <th>Email</th>
                        <th>Created</th>
                        <th>Updated</th>
                    </tr>
                </thead>
                <tbody>
                @foreach($users as $user)
                    <tr>
                        <td>{{$user->id}}</td>
                        <td>{{$user->name}}</td>
                        <td>{{$user->email}}</td>
                        <td>{{$user->created_at}}</td>
                        <td>{{$user->updated_at}}</td>
                    </tr>
                @endforeach
                </tbody>
            </table>
        </div>
    </div>
</div>
@endsection

- Full code file UserController.php như sau:

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Carbon\Carbon;
use App\Exports\UsersExport;
use App\Exports\UsersExportQuery;
use App\Exports\UsersExportView;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $users = User::all();
        return View('list-users')->with(array('users'=>$users));
    }

    public function export(Request $request) 
    {
        $type = $request->type;
       
        if($request->created!="" && $request->template==""){
            $now = new Carbon($request->created);
            $year = $now->year;
            $created = $request->created;
            return Excel::download(new UsersExportQuery($year,$created),'users.'.$type);
        }else if($request->created=="" && $request->template!=""){

            return Excel::download(new UsersExportView($request->template), 'users.'.$type);
        }
        return Excel::download(new UsersExport, 'users.'.$type);
    }
}

- Giờ thì để có thể export, ta cần cài đặt file web.php trong thư mục routes/web.php 

Route::get('/user','UserController@index');
Route::get('/export/{user}','UserController@export')->name('export');

- Vậy là ta có thể export được rồi!