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.