Search code examples
phpexcellaravelexportlaravel-excel

Laravel excel multi sheet using view return multi sheets but empty


I am trying to export a sheet with multiple workbooks and to generate each workbook from a view. I have created 5 different .blade files containing HTML tables and want to generate each work book from each .blade file.

I am trying to export a sheet with multiple workbooks and to generate each workbook from a view. I have created 5 different .blade files containing HTML tables and want to generate each work book from each .blade file.

<?php
namespace App\Exports;
use App\Models\GenerateQrCode;
use App\Models\Scan;

use DateInterval;
use DatePeriod;
use DateTime;
use Hashids\Hashids;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Excel;

class ScansExport implements FromView,WithMultipleSheets {
    public $id;
    public $from;
    public $to;
    public function __construct($id,$request) {
        $this->from = $request['from'];
        $this->to = $request['to'];
        $this->id = $id;
    }

    public function getScansCountGroupBy($id, $field) {
        return Scan::where('qr_code_id', $id)->select($field, \DB::raw('count(*) as scans'))->groupBy($field)->orderBy('created_at', 'asc')->get();
    }

    public function view(): View {
        $id = \Hashids::decode($this->id)[0];
        $data['qrCode'] = GenerateQrCode::find($id);
        if ($this->from && $this->to) {
            $from = $this->from . ' 00:00:00';
            $to = $this->to . ' 23:59:59';

            $data['from'] = $this->from;
            $data['to'] = $this->to;
        } else {
            $from = date('Y-m-d', strtotime("-30 days")) . ' 00:00:00';
            $to = date('Y-m-d') . ' 23:59:59';

            $data['from'] = date('Y-m-d', strtotime("-30 days"));
            $data['to'] = date('Y-m-d');
        }
        $data['scansList'] = Scan::where('qr_code_id', $id)->whereBetween('created_at', [$from, $to])->orderBy('created_at', 'desc')->get();
        $data['firstScan'] = Scan::where('qr_code_id', $id)->whereBetween('created_at', [$from, $to])->first();

        $data['scansDataPoints'] = [];
        $data['uniqueUsersDataPoints'] = [];
        if (!empty($data['firstScan'])) {
            $data['countryCount'] = Scan::where('qr_code_id', $id)->whereBetween('created_at', [$from, $to])->where('country', $data['firstScan']->country)->count();
            $data['deviceCount'] = Scan::where('qr_code_id', $id)->whereBetween('created_at', [$from, $to])->where('device', $data['firstScan']->device)->count();

            /*
            ** Countries
            ** Cities
            ** Languages
            */

            $data['countries'] = $this->getScansCountGroupBy($id, 'country');
            $data['cities'] = $this->getScansCountGroupBy($id, 'city');
            $data['languages'] = $this->getScansCountGroupBy($id, 'language');

            /*
            ** Devices
            ** Platforms
            ** Browsers
            */

            $data['devices'] = $this->getScansCountGroupBy($id, 'device');
            $data['platforms'] = $this->getScansCountGroupBy($id, 'platform');
            $data['browsers'] = $this->getScansCountGroupBy($id, 'browser');

            // $period = new \DatePeriod(
            //     new \DateTime(date('Y-m-d', strtotime("-30 days"))),
            //     new \DateInterval('P1D'),
            //     new \DateTime(date('Y-m-d', strtotime("+1 days")))
            // );

            $period = new \DatePeriod(
                new \DateTime($from),
                new \DateInterval('P1D'),
                new \DateTime($to)
            );

            /*
            ** Scans Graph
            */

            $scans = Scan::where('qr_code_id', $id)->whereBetween('created_at', [$from, $to])->select(\DB::raw('DATE(created_at) as date'), \DB::raw('count(*) as scans'))->groupBy('date')->orderBy('created_at', 'asc')->get()->toArray();

            $scansDataPoints = array();

            foreach ($period as $key => $value) {
                $date = $value->format('Y-m-d');
                $index = array_search($value->format('Y-m-d'), array_column($scans, 'date'));

                if ($index !== false) {
                    $scansDataPoints[$date] = $scans[$index]['scans'];
                } else {
                    $scansDataPoints[$date] = 0;
                }
            }

            $data['scansDataPoints'] = $scansDataPoints;

            /*
            ** Unique Users Graph
            */

            $unique_users = Scan::where('qr_code_id', $id)->whereBetween('created_at', [$from, $to])->select(\DB::raw('DATE(created_at) as date'), \DB::raw('count(DISTINCT ip) as unique_count'))->groupBy('date')->orderBy('created_at', 'asc')->get()->toArray();
            $uniqueUsersDataPoints = array();

            foreach ($period as $key => $value) {
                $date = $value->format('Y-m-d');
                $index = array_search($value->format('Y-m-d'), array_column($unique_users, 'date'));

                if ($index !== false) {
                    $uniqueUsersDataPoints[$date] = $unique_users[$index]['unique_count'];
                } else {
                    $uniqueUsersDataPoints[$date] = 0;
                }
            }

            $data['uniqueUsersDataPoints'] = $uniqueUsersDataPoints;
        }
//        $array = [
//            view('frontend.dashboard.export-statistics.qrcode-countries', $data),
//            view('frontend.dashboard.export-statistics.qrcode-cities', $data),
//        ];

        return $data;
    }

    public function sheets(): array {
        $data = $this->view();
   
        return [
            view('frontend.dashboard.export-statistics.qrcode-countries', $data),
            view('frontend.dashboard.export-statistics.qrcode-cities', $data),
        ];
    }
}

Solution

  • You cannot pass views as sheets. You must create individual sheet exports for each view. Then you can combine them using the WithMultipleSheets concern.

    CountriesExport.php

    class CountriesExport implements FromView
    {
        public function view(): View
        {   
            $data = ...
    
            return view('frontend.dashboard.export-statistics.qrcode-countries', $data);
        }
    }
    

    CitiesExport.php

    class CitiesExport implements FromView
    {
        public function view(): View
        {   
            $data = ...
    
            return view('frontend.dashboard.export-statistics.qrcode-cities', $data);
        }
    }
    

    ScansExport.php

    class ScansExport implements WithMultipleSheets 
    { 
        public function sheets(): array 
        {   
            return [
                new CountriesExport(),
                new CitiesExport(),
            ];
        }
    }