Skip to main content
Tutorial Free

Filament: Export Record to PDF - Two Ways

June 29, 2023
3 min read

Exporting data to PDF is a very common feature. This tutorial will show how to do it in the Filament admin panel: we will export a single record to PDF using Blade View and barryvdh/laravel-dompdf package.

PDF export action button

We will use the official Filament demo project for the demo code, adding a PDF download to the OrderResource. The source code for the original demo it can be found on the GitHub here.


Method 1: Filament Action

First, let's see how we can export into a PDF from Filament action.

app/Filament/Resources/Shop/OrderResource.php:

use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Blade;
 
class OrderResource extends Resource
{
// ...
 
public static function table(Table $table): Table
{
return $table
->columns([
// ...
])
->filters([
// ...
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\Action::make('pdf')
->label('PDF')
->color('success')
->icon('heroicon-s-download')
->action(function (Model $record) {
return response()->streamDownload(function () use ($record) {
echo Pdf::loadHtml(
Blade::render('pdf', ['record' => $record])
)->stream();
}, $record->number . '.pdf');
}),
])
->bulkActions([
// ...
]);
}
 
// ...
}

The first import code here is what we return. This response comes from the Livewire where first we pass the content and the second parameter is the filename.

For the PDF content, we use the loadHTML method from the barryvdh/laravel-dompdf package, and we stream it. To get the HTML we are using the Blade facade to render the Blade file and passing the data.

After this, we have a PDF button in the Orders list.

PDF export action button

Now, in the Blade file, you can add any data you need about the record. I called this View pdf.blade.php.

resources/views/pdf.blade.php:

<div>Number: {{ $record->number }}</div>
<div>Customer: {{ $record->customer->name }}</div>
<div>Status: {{ $record->status }}</div>
<div>Total price: {{ $record->total_price }}</div>
<div>Order Date: {{ $record->created_at }}</div>

After clicking the PDF button, the PDF will be downloaded with basic information about the order.

PDF view


Method 2: Using Controller and Route

Here's an alternative approach. First, we need a Controller and a Route.

php artisan make:controller PdfController

routes/web.php:

use App\Http\Livewire\Form;
use App\Http\Controllers\PdfController;
 
\Illuminate\Support\Facades\Route::get('form', Form::class);
 
Route::get('pdf/{order}', PdfController::class)->name('pdf');

In the Controller, we can generate the PDF from the View using loadView method from the barryvdh/laravel-dompdf package and chaining it to download.

app/Http/Controllers/PdfController.php:

use App\Models\Shop\Order;
use Barryvdh\DomPDF\Facade\Pdf;
 
class PdfController extends Controller
{
public function __invoke(Order $order)
{
return Pdf::loadView('pdf', ['record' => $order])
->download($order->number. '.pdf');
}
}

We need to call this Route in the Filament action.

app/Filament/Resources/Shop/OrderResource.php:

class OrderResource extends Resource
{
// ...
 
public static function table(Table $table): Table
{
return $table
->columns([
// ...
])
->filters([
// ...
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\Action::make('pdf')
->label('PDF')
->color('success')
->icon('heroicon-o-document-download')
->url(fn (Order $record) => route('pdf', $record))
->openUrlInNewTab(),
])
->bulkActions([
// ...
]);
}
 
// ...
}

And that's it. After clicking the PDF button, it will open the URL in a new tab and will download the generated PDF file.


If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.

Enjoyed This Tutorial?

Get access to all premium tutorials, video and text courses, and exclusive Laravel resources. Join our community of 10,000+ developers.

Comments & Discussion

S
szopenek17 ✓ Link copied!

Hello, First method deletes the template view for pdf from resource. Why ?

N
Nerijus ✓ Link copied!

deleteCachedView isn't needed

S
szopenek17 ✓ Link copied!

Yeah i know but from "Also, we don't need this cached View, so we are setting it to be deleted." It means cached view. So why it deletes my orginal template from resources/views/pdf.blade.php ?

N
Nerijus ✓ Link copied!

It was a mistake. Updated text.

N
nikonachev ✓ Link copied!

This is a very helpful topic. In my case I use method 1: Filament Action. How can I use JavaScript in loaded Blade? I have this simple Blade template:

Test PDF

When I execute the code explained in Method 1 in the generated PDF is outputted “Test PDF” instead “I have changed!”. Where is my mistake and how to solve this problem? Thank you.

N
nikonachev ✓ Link copied!

Test PDF

N
Nerijus ✓ Link copied!

I guess then you cant? Would would you even want to use it?

N
nikonachev ✓ Link copied!

I want to use JavaScript to insert dynamically HTML using insertAdjacentHTML() but DomPdf does not take in account the JavaScript contained in the blade Template. And also I don’t know why I can’t paste in the comments the source of the Blade.

N
Nerijus ✓ Link copied!

If its dompdf thing cant help

N
nikonachev ✓ Link copied!

OK. Thank you.

KI
Khairul Imran ✓ Link copied!

How to view pdf in browser without download it?

M
Modestas ✓ Link copied!

Change ->download(...) to ->stream(...) and it should work

KI
Khairul Imran ✓ Link copied!

Nice. It work. Tq

MG
Marco Garcia ✓ Link copied!

Hello and if I would like to open a modal with the pdf file what could you suggest me?

M
Modestas ✓ Link copied!

If you want a modal with the PDF, you do need:

https://laraveldaily.com/post/filament-table-row-action-view-modal-infolist

Or in other words, your modal has to be an infolist and there you have to create a custom HTML component (ViewEntry) to load the PDF in an iframe. There is no other way at this point

E
EmJay646 ✓ Link copied!

How can i pass the pdf to the ViewEntry? viewData does not accept a closure?

DA
Domingo Añez ✓ Link copied!

With filamentphp v3, Laravel 10.34.2, PHP 8.2.0 I get the following error: Unable to prepare route [pdf/{record}] for serialization. Another route has already been assigned name [pdf]. in web.php: Route::get('pdf/{record}', PdfController::class)->name('pdf');

In PdfResourse.php Action::make(('Pdf')) ->icon('heroicon-o-printer') ->url(fn (Invoices $record) => route('pdf', $record)) ->openUrlInNewTab(),**

How do I resolve the routing error? *

M�
Michal “Spil” Korol ✓ Link copied!

if its only name issue, just change route name ->name('another_pdf')

also refactor your code where you use routes by names

YM
Yordanis Martinez ✓ Link copied!

I have used method 1. How can I add a custom CSS and JS file to my pdf.blade.php template?

N
Nerijus ✓ Link copied!

You can't add js and you shouldn't. As for CSS write a custom styles

V
Vito ✓ Link copied!

How do I customize the appearnace of the exported PDF?

For example: I wish to add my company logo and move around some of the locations of each field. A result would be a nice looking customer facing Invoice.

M
Modestas ✓ Link copied!

Since this is a view based PDF - you have to modify the view template itself. Anything you put inside of it - will be in your PDF.

We don't have a tutorial for this, as it is as simple as creating the HTML content

KN
Kasper Nowak ✓ Link copied!

Does this also work for table header actions, or only for row actions?

I need to export/print a pdf of an admin panel resource table.

M
Modestas ✓ Link copied!

This should work on header action too

DH
Denis Hancock ✓ Link copied!

It would be interesting to see how everyone does this not on a record but on the resultant table in filament. IE if you have a table that's the result of search or filter, how can you STREAM that to a PDF - Thanks for thoughts

N
Nerijus ✓ Link copied!

You would get selected records from the table component. Plenty of such questions on the filament discord, should check their

DH
Denis Hancock ✓ Link copied!

Thanks

J
Javaabu ✓ Link copied!

Using the controller method, how can I make sure that the route is protected with the same authentication as the Filament portal? That seems like something very important that should be implemented.

N
Nerijus ✓ Link copied!

It's laravel. Add authorization in whate way you want

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.