A Guide to Work with PDF Generation in FilamentPHP

A Guide to Work with PDF Generation in FilamentPHP

Introduction

FilamentPHP is an amazing piece of tool that helps in rapidly building Admin Panels. It consists of everything you need to build amazing and performant admin panels.

But while building Admin panels, there are cases where you have to build additional features like Generating Invoices/QR Codes. And it can be a bit tricky to build these features when you are working with tools like FilamentPHP.(unless they provide these features out of the box)

So in this blog, we'll be looking at how we can generate PDFs in a Filament-based Admin Panel.

Prerequisites

I'm assuming that you already have a working admin panel built using Filament.

And if you don't have one, you can take a reference from this repository (this also contains the code demonstrated in this blog)

And if you are relatively new to FilamentPHP, you can take this beginners course which will get you up and running with Filament.

Installation

For working with PDFs a bit easier, I'm gonna be using an Invoice generator package called laraveldaily/laravel-invoices

So let's start by installing this package:

composer require laraveldaily/laravel-invoices

Implementation

Let's start by adding a new action in the actions functions, we'll give it a name of "Download Pdf", pass an heroicon-o-document-download Icon and in the URL function, we'll get the record by passing in a closure and then redirect it to student.pdf.download route and pass the record as a parameter. One more thing to note here is that we need to pass the model in the closure as $record, this will throw an error if you name it something else.

We're also passing in the openUrlInNewTab() function, its just a personal preference and also depends on the use case.

->actions([
            // ...
            Tables\Actions\Action::make('Download Pdf')
                ->icon('heroicon-o-document-download')
                ->url(fn (Student $record) => route('student.pdf.download', $record))
                ->openUrlInNewTab(),
            ])

Let's go ahead and define the route now, this code is self explanatory:

Route::get('/{record}/pdf/download', [DownloadPdfController::class, 'download'])->name('student.pdf.download');

Let's look into the DownloadPdfController

<?php

namespace App\Http\Controllers;

use App\Models\Student;
use Illuminate\Http\Request;
use LaravelDaily\Invoices\Invoice;
use LaravelDaily\Invoices\Classes\Buyer;
use LaravelDaily\Invoices\Classes\InvoiceItem;

class DownloadPdfController extends Controller
{
    public function download(Student $record)
    {
        $customer = new Buyer([
            'name'          => 'John Doe',
            'custom_fields' => [
                'email' => 'test@example.com',
            ],
        ]);

        $item = (new InvoiceItem())->title('Service 1')->pricePerUnit(2);

        $invoice = Invoice::make()
            ->buyer($customer)
            ->discountByPercent(10)
            ->taxRate(15)
            ->shipping(1.99)
            ->addItem($item);

        return $invoice->stream();
    }
}

The code inside the download function contains the logic for the PDF generation, and depending on your use case, you can define the logic accordingly.

For demonstration, I've copy-pasted this demo code from the laravel-invoices package.

We're done with the implementation part, it's finally time to test it out.

Testing

If we go ahead and refresh our table, we should see a Download Pdf beside the Edit and Delete buttons. And if Clicked, will open a new tab in which our PDF gets rendered.

So yeah, this is how to implement PDF generation in a filament-based app.


FilamentPHP Course

I guess you've already figured out that I'm loving the TALL stack along with FilamentPHP and I have been exploring it a lot lately, and to further improve your skills and help you get started, I have created a Udemy Course based on this stack, where we'll build multiple practical projects and learn a ton of stuff along the way.

You can check out the Course here


Conclusion

This lesson is actually a part of my Course about FilamentPHP, where we'll build a Support Ticket System from Scratch and also learn a ton of stuff along the way.

You can check out the Course here

And, If you prefer a video-based tutorial, you can check out this video

And finally, If you liked this article and wanna see more content like this, you can follow me on Twitter, I'm most active there.