Insights into Company
← PHP & Laravel

Excel & PDF Reports

01 Choosing an Excel library

Solution and explanation

  • Maatwebsite/Laravel-Excel is the common Laravel integration built on PhpSpreadsheet.
  • PhpSpreadsheet gives lower-level control, while Spatie Simple Excel is useful for memory-efficient streaming of simple, very large files.
Run this example
// Common Laravel choice
composer require maatwebsite/excel

// Lower-level spreadsheet engine
composer require phpoffice/phpspreadsheet
Hands-on challenge

Compare the libraries for a formatted monthly report and a two-million-row CSV export.

Quick check

Which statement is correct?

02 Installing Excel and PDF packages

Solution and explanation

  • Install only the packages the application needs and commit composer.json plus composer.lock.
  • DomPDF renders controlled Blade HTML without requiring Chromium.
Run this example
composer require maatwebsite/excel barryvdh/laravel-dompdf
composer show maatwebsite/excel
composer show barryvdh/laravel-dompdf
Hands-on challenge

Install in a feature branch and confirm Composer selected versions compatible with the project PHP version.

Quick check

Which statement is correct?

03 Creating a Laravel Excel export

Solution and explanation

  • An export class describes the rows and headings independently from the HTTP controller.
  • Concerns compose features without turning the controller into report logic.
Run this example
namespace App\Exports;

use App\Models\User;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;

final class UsersExport implements FromQuery, WithHeadings {
 public function query() { return User::query()->select('id','name','email','created_at'); }
 public function headings(): array { return ['ID','Name','Email','Created At']; }
}
Hands-on challenge

Generate UsersExport and export only columns approved for the report.

Quick check

Which statement is correct?

04 Exporting large datasets safely

Solution and explanation

  • Avoid loading a massive dataset with get().
  • Query-based or generator-based exports, chunk reading, queues and temporary object storage keep HTTP memory stable.
Run this example
final class JobsExport implements FromQuery, ShouldQueue {
 public function query() {
  return Job::query()->published()->select('id','title','company_id');
 }
}
Hands-on challenge

Test the export with 100,000 factory records and monitor peak memory.

Quick check

Which statement is correct?

05 Downloading an Excel report

Solution and explanation

  • The controller authorizes the report, constructs the export and returns Excel::download.
  • Filters should be validated and passed explicitly.
Run this example
use Maatwebsite\Excel\Facades\Excel;

public function excel(ReportFilterRequest $request) {
 $this->authorize('exportUsers');
 return Excel::download(new UsersExport($request->validated()), 'users-report.xlsx');
}
Hands-on challenge

Protect a candidate export so only an authorized owner can download it.

Quick check

Which statement is correct?

06 Choosing a PDF renderer

Solution and explanation

  • DomPDF converts conservative HTML/CSS to PDF and works well for invoices and reports.
  • Spatie Laravel PDF or Browsershot uses Chromium when exact modern CSS rendering is essential.
Run this example
use Barryvdh\DomPDF\Facade\Pdf;

$pdf = Pdf::loadView('reports.users-pdf', ['users'=>$users]);
return $pdf->download('users-report.pdf');
Hands-on challenge

Choose a renderer for an ATS resume and another for a pixel-perfect dashboard printout.

Quick check

Which statement is correct?

07 Building a PDF Blade template

Solution and explanation

  • A PDF view should have deterministic dimensions, embedded print-safe CSS, escaped values and a layout supported by the selected renderer.
Run this example
<!doctype html>
<html><head><style>
table{width:100%;border-collapse:collapse}
th,td{border:1px solid #ddd;padding:8px;text-align:left}
</style></head><body>
<h2>Users List</h2>
@foreach($users as $user) <p>{{ $user->name }} — {{ $user->email }}</p> @endforeach
</body></html>
Hands-on challenge

Render malicious-looking user text and confirm Blade escapes it in the PDF HTML.

Quick check

Which statement is correct?

08 Defining secure report routes

Solution and explanation

  • Use named controller routes protected by authentication, authorization and appropriate throttling.
  • Keep report creation out of anonymous GET endpoints when it is expensive or sensitive.
Run this example
Route::middleware(['auth','throttle:reports'])->group(function(){
 Route::get('/reports/users.xlsx',[ReportController::class,'excel'])->name('reports.users.excel');
 Route::get('/reports/users.pdf',[ReportController::class,'pdf'])->name('reports.users.pdf');
});
Hands-on challenge

Add policy checks and a feature test proving an ordinary student receives 403.

Quick check

Which statement is correct?