phplaravelemaillaravel-8laravel-mail

How to attach multiple files to Laravel 8 Mail from laravel Excel 3.1


I am trying to send 2 files attached to my mail but it is only attaching the first file and not the second file at the mail...

What I have been trying:

Mail Controller:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

use App\Exports\ProductInventoryExport;
use App\Exports\SalesReport;
use App\Exports\CustomerOrderReceipt;
use Maatwebsite\Excel\Facades\Excel;


class DailyReports extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the message envelope.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'Daily Reports',
        );
    }

    /**
     * Get the message content definition.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mails.daily-reports',
        );
    }


    public function build()
    {
        return $this->from('sendmail@gmail.com')
        ->markdown('mails.daily-reports')
        ->attach(
            Excel::download(new ProductInventoryExport, 'ProductInventory.xlsx')->getFile(), ['as' => 'ProductInventory.xlsx']
        )
        ->attach(
            Excel::download(new SalesReport('daily', 0, 0), 'DailySalesReport.xlsx')->getFile(), ['as' => 'DailySalesReport.xlsx'], 
            //It's not attaching this file Idk why...
        );
    }
}

I am Calling the function like this:

use App\Mail\DailyReports;
use Illuminate\Support\Facades\Mail;
public function sendMail()
{
    Mail::to('tomail@gmail.com')->send(new DailyReports);
}

Results:

Here, it only attaches the first file (ProductInventory.xlsx)...

The mail I am receiving:

The Mail

I tried a few other methods like putting my files in an Array and looping through it but I got the same result that it's only sending the first file...

Thanks in advance


Solution

  • It seems that you cannot attach 2 downloaded files, even though 1 works. Unsure why that is.

    You need to use store instead (https://docs.laravel-excel.com/3.1/exports/store.html).

    What you can do is create a disk in config/filesystems, for example:

            'excel' => [
                'driver' => 'local',
                'root'   => storage_path('app/excel-downloads'),
            ],
    

    Then change the build method inside your DailyReports to:

        public function build()
        {
            // Store exports and add their file names to attachments array
            $attachments = collect([]);
    
            $fileName = 'ProductInventory.xlsx';
            // Arguments here are export, file name and the disk to store it to. You could also leave out 'excel', then it would be stored inside your default disk.
            Excel::store(new ProductInventoryExport, $fileName, 'excel');
            $realAttachments->push($fileName);
    
            $fileName = 'DailySalesReport.xlsx';
            Excel::store(new SalesReport('daily', 0, 0), $fileName, 'excel');
            $realAttachments->push($fileName);
    
            // Start build email
            $email = $this
                ->from('sendmail@gmail.com')
                ->markdown('emails.daily-reports');
    
            // Attach the files to the email
            foreach ($attachments as $fileName) {
                // Adjust the next line based on where you store the files
                $email->attach(storage_path() . "/app/excel-downloads/" . $fileName);
            }
    
            return $email;
        }
    

    Here's the code without comments if you use the default disk to store the Excel files:

        public function build()
        {
            $attachments = collect([]);
    
            $fileName = 'ProductInventory.xlsx';
            Excel::store(new ProductInventoryExport, $fileName);
            $realAttachments->push($fileName);
    
            $fileName = 'DailySalesReport.xlsx';
            Excel::store(new SalesReport('daily', 0, 0), $fileName);
            $realAttachments->push($fileName);
    
            $email = $this
                ->from('sendmail@gmail.com')
                ->markdown('emails.daily-reports');
    
            foreach ($attachments as $fileName) {
                $email->attach(storage_path() . "/app/" . $fileName);
            }
    
            return $email;
        }