Laravel excel 多表使用视图返回多表但为空

问题描述

我正在尝试导出包含多个工作簿的工作表并从视图中生成每个工作簿。我创建了 5 个不同的 .blade 文件,其中包含 HTML 表格,并希望从每个 .blade 文件生成每个工作簿。

我正在尝试导出包含多个工作簿的工作表并从视图中生成每个工作簿。我创建了 5 个不同的 .blade 文件,其中包含 HTML 表格,并希望从每个 .blade 文件生成每个工作簿。

<?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',$to])->first();

        $data['scansDataPoints'] = [];
        $data['uniqueUsersDataPoints'] = [];
        if (!empty($data['firstScan'])) {
            $data['countryCount'] = Scan::where('qr_code_id',$to])->where('country',$data['firstScan']->country)->count();
            $data['deviceCount'] = Scan::where('qr_code_id',$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',$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',\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',//        ];

        return $data;
    }

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

解决方法

您不能将视图作为工作表传递。您必须为每个视图创建单独的图纸导出。然后您可以使用 WithMultipleSheets 关注点组合它们。

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(),];
    }
}