Search code examples
excellaravellaravel-excel

How to build Excel with two sheets and download?


I use Laravel Excel and that is full code:

<?php

namespace App\Http\Controllers;

use App\Event;
use App\Visitor;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Facades\Excel;
use Exportable;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;

class VisitorsSheet implements FromQuery, WithTitle
{

    private $idEvent;

    public function __construct($idEvent)
    {

        $this->idEvent = $idEvent;
    }

    public function query()
    {
        return Visitor::where("idEvent", $this->idEvent)->get();
    }

    public function title(): string
    {
        return 'Visitors';
    }
}

class EventSheet implements FromQuery, WithTitle
{
    private $idEvent;

    public function __construct($idEvent)
    {

        $this->idEvent = $idEvent;
    }

    public function query()
    {
        return Event::where("idEvent", $this->idEvent)->get();
    }

    public function title(): string
    {
        return 'Event №' . $this->idEvent;
    }
}

class ArchivingExport implements WithMultipleSheets
{

    private $eventId;

    public function __construct($eventId)
    {

        $this->eventId = $eventId;
    }

    public function sheets(): array
    {
        $sheets = [];
        $sheets[] = new EventSheet($this->eventId);
        $sheets[] = new VisitorsSheet($this->eventId);

        return $sheets;
    }
}

class ArchivingController extends Controller
{

    private $file = "settings_archive.json";

    public function __construct()
    {
        date_default_timezone_set("Asia/Tei");
    }

    private function formatName($event)
    {
        return $event->date . '_' . $event->name . '.xlsx';
    }

    public function index()
    {

        $download = [];

            try {
                $events = Event::where("status", 1)->where("archived", 0)->get();
                foreach ($events as $key => $event) {
                    $download[] = new ArchivingExport($event->idEvent); //->download($this->formatName($event));
                }

                return $download;

            } catch (Exception $e) {
                 return \json_decode([
                    'status' => false,
                    'message' =>  $e->getMessage()
                ]);

            }


       return \json_decode([
            'status' => false
        ]);

    }

}

As you can see in class ArchivingController in index method I try to build sheets:

foreach ($events as $key => $event) {
   $download[] = new ArchivingExport($event->idEvent); //->download($this->formatName($event));
}

I get ready objects in $download[], but I dont know how to download them? It should be ready Excel file.

I tried to call for each object:

->download($this->formatName($event));

But there is not method download inside


Solution

  • It is not possible to send more than one file simultaneously over the same request with the HTTP protocol. Laravel also does not support this.

    You have to pack the files in, for example, a zip file.

    A popular package is Zipper