Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

noblemfd's avatar

How to Perform Advance Format using Maatwebsite Export

I am trying to export my report to excel in my Laravel 5.8 project using Maatwebsites:

In Laravel-5.8, I am trying to export to Excel using Maatwebsite:

<?php

namespace App\Exports;

use App\User;
use Auth;

class StudentExport implements FromCollection, ShouldAutoSize, WithHeadings, WithMappings
{

    private $headings = [
        'Student ID', 
        'Name',
        'Class',
        'Status',
        'Teacher'
    ];

    public function collection()
    {
        $userCompany = Auth::user()->company_id;
        $userEmployee = Auth::user()->employee_id;
        $userId = Auth::user()->id;
        $employeecode = Auth::user()->employee_code;

        $current_terms = DB::table('appraisal_identity')->select('term_name')->where('company_id', $userCompany)->where('is_current', 1)->first()->term_name;
        $identities = DB::table('appraisal_identity')->select('id')->where('company_id', $userCompany)->where('is_current', 1)->pluck('id');
        $publishedgoals = AppraisalGoal::select('employee_code')->where('is_published', 1)->where('appraisal_identity_id', $identities)->where('company_id', $userCompany)->groupBy('employee_code')->get();  


        $published_goals = DB::table('hr_students AS e')
                    ->join('hr_employees AS em','em.id','=','e.teacher_id')
                     ->select(
                        'e.student_id',
                        DB::raw('CONCAT(e.first_name, " ", e.last_name) AS full_name'),
                        'e.student_class,
                        DB::raw('(CASE WHEN e.is_status = 3 THEN "Excellent" WHEN e.is_status = 2 THEN "Good" WHEN e.is_status = 1 THEN "Average" ELSE "Pass" END) AS student_status') 
                        DB::raw('CONCAT(em.first_name, " ", em.last_name) AS teacher_name')
                        
                 )
                    ->whereIn('e.student_id', $publishedgoals)
                ->distinct()
                ->get();

            $published_goals = $published_goals->unique('student_id');
       
           return collect($published_goals);
    } 

public function map($published_goals): array
{
    return [
       $published_goals->student_id,
       $published_goals->full_name,
       $published_goals->student_class,
       $published_goals->student_status,
       $published_goals->teacher_name,
   ];
 }  


public function headings() : array
{

    return $this->headings;
}    

public function registerEvents() : array
{
    return [
        AfterSheet::class    => function(AfterSheet $event) {
            $cellRange = 'A4:E4'; // All headers
            $event->sheet->getDelegate()->getStyle($cellRange)->getFont()->setSize(14);
            $event->sheet->getDelegate()->getStyle($cellRange)->getFont()->getColor()
                   ->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
            $event->sheet->getDelegate()->getStyle($cellRange)->getFill()
                   ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
                   ->getStartColor()->setARGB('FF17a2b8');
            $event->sheet->setAutoFilter($cellRange);
        },
    ];
  }   

}

I have written the code above to get this resuld:

https://i.stack.imgur.com/IJFTA.png

However I want to:

However I want to:

  1. Merge A1:E1 and align center as STUDENT TERMINATION REPORT

  2. I want to make D2 to have the output of these variables together: $current_terms - $identities (For example, if $current_terms = 1st Term and $identities = 20. Then It will be 1st Term - 20 )

  3. I want to display the current date and time as A2:B2 (Report Date & Time: 20 July 2020 10:00 p.m.)

  4. A4:E4 as the Heading (A4->Student ID, B4->Name, C4->Class, D4->Status, E4->Teacher

The result should be as shown below:

https://i.stack.imgur.com/bnxHO.png

How do I modify the code and formatting to achieve this?

Thank you

0 likes
7 replies
MarianoMoreyra's avatar

Hi again @noblemfd !

Let me see if I can help you with most of your items:

  1. Merge A1:E1 and align center as STUDENT TERMINATION REPORT

Try with something like this:

$event->sheet->getDelegate()->mergeCells('A1:E1');
$event->sheet->getDelegate()
    ->getStyle('A1')
    ->getAlignment()
    ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
$event->sheet->getDelegate()->setCellValue('A1', 'STUDENT TERMINATION REPORT');
  1. I want to make D2 to have the output of these variables together: $current_terms - $identities (For example, if $current_terms = 1st Term and $identities = 20. Then It will be 1st Term - 20 )
$event->sheet->getDelegate()->setCellValue('D2', $current_terms . ' - ' . $identities);
  1. I want to display the current date and time as A2:B2 (Report Date & Time: 20 July 2020 10:00 p.m.)

Here you can apply a mix of what I've showed you at items 1 and 2 if they actually work.

  1. A4:E4 as the Heading (A4->Student ID, B4->Name, C4->Class, D4->Status, E4->Teacher

I understand that you got this working already.

Anyway, it's all at the PhpSpreadsheet documentation, for example, how to access a cell: https://phpspreadsheet.readthedocs.io/en/latest/topics/accessing-cells/

Although you have to adapt it to your particular code, and Laravel Excel need, for example, using getDelegate()

Hope this helps!!

MarianoMoreyra's avatar

@noblemfd just in cases you already saw my previous answer, I edited it because I forgot to show the STUDENT TERMINATION REPORT at the merged cells on row 1.

MarianoMoreyra's avatar

Also, as I've pointed out in a previous answer to one of your questions, remember to implement the WithCustomStartCell concern in order to be able to tell the library to start the exported table at cell A4 and implement the following method:

    public function startCell(): string
    {
        return 'A4';
    }
noblemfd's avatar

@marianomoreyra - I got this error:

Use of undefined constant current_terms

Use of undefined constant identities

From my code as shown above, I returned and mapped only $published_goals which I used for A4:E4.

How do I do likewise for $current_terms and $identities ?

Thanks

MarianoMoreyra's avatar
Level 25

@noblemfd I'm sorry. It's true, you don't have those variables at that instance.

But, I don't see that you are using them at the collection() method, so I guess you could just move those two lines to the AfterSheet event, that way you can use them.

Or you could add two additional private variables and then at collection method you'll do:

$this->current_terms = DB::table('appraisal_identity')
    ->select('term_name')
    ->where('company_id', $userCompany)
    ->where('is_current', 1)
    ->first()
    ->term_name;

$this->identities = DB::table('appraisal_identity')
    ->select('id')
    ->where('company_id', $userCompany)
    ->where('is_current', 1)
    ->pluck('id');

assigning to $this->current_terms and $this->identities instead of the local function variables

and then you can use them at the AfterSheet event:

$event->sheet->getDelegate()
    ->setCellValue('D2', $this->current_terms . ' - ' . $this->identities);

Please or to participate in this conversation.