For a custom Laravel based CRM project, you always needed the dynamic PDF generation feature for the customer’s leads table to easily print the basic lead information on pdf. After googling for some time, I stumbled upon a very nice DOMPDF Wrapper for Laravel at GitHub, laravel-dompdf.
If you want to know basic laravel functionality, check out my article Laravel Crud Example From Scratch. For this example, we use the Dompdf library.
It is the style-driven renderer: it will download and read external stylesheets, inline style tags, and individual HTML elements’ style attributes. It also supports most presentational HTML attributes.
Laravel PDF
To generate a PDF in Laravel application, use the dompdf package. Dompdf is an HTML to PDF converter. The dompdf is (mostly) the CSS 2.1 compliant HTML layout and rendering engine written in PHP language.
You can generate a pdf file from a view using DomPDF. To export into PDF, We need to write the view file. Then, we will write the HTML code and load data dynamically from the database as per the requirement. After that, we will export this view as a PDF file.
If you are using an older version of Laravel, check out this How To Generate PDF In Laravel 5 tutorial.
Install Laravel using the following command.
composer create-project --prefer-dist laravel/laravel laravelPDF
Now, go inside the folder and open the folder inside the visual studio code.
Step: 1 Download the laravel-dompdf package
Type the following command to install the laravel-dompdf package.
composer require barryvdh/laravel-dompdf
➜ laravel6 git:(master) composer require barryvdh/laravel-dompdf Using version ^0.8.5 for barryvdh/laravel-dompdf ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 5 installs, 0 updates, 0 removals - Installing sabberworm/php-css-parser (8.3.0): Downloading (100%) - Installing phenx/php-svg-lib (v0.3.3): Downloading (100%) - Installing phenx/php-font-lib (0.5.1): Downloading (100%) - Installing dompdf/dompdf (v0.8.3): Downloading (100%) - Installing barryvdh/laravel-dompdf (v0.8.5): Downloading (100%) dompdf/dompdf suggests installing ext-imagick (Improves image processing performance) dompdf/dompdf suggests installing ext-gmagick (Improves image processing performance) Writing lock file Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: barryvdh/laravel-dompdf Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: laravel/ui Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully.
Step: 2 Configure the package Laravel application
So go to a config >> app.php and add the following configuration.
'providers' => [ .... Barryvdh\DomPDF\ServiceProvider::class, ], 'aliases' => [ .... 'PDF' => Barryvdh\DomPDF\Facade::class, ],
Here we are registering a PDF register provider for our application and set the alias for it. So when we need to create PDF, we need to include it in our namespace like,
use PDF;
Then, we instantiate a PDF class and use its API to enhance the generated PDF file further.
Step: 3 Create a layout blade file.
Inside the resources >> views folder, create a new file called layout.blade.php.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Laravel CRUD Example</title> <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" /> </head> <body> <div class="container"> @yield('content') </div> <script src="{{ asset('js/app.js') }}" type="text/js"></script> </body> </html>
Step 4: Create model and migration files
We will create model and migration files using the following command.
php artisan make:model Disneyplus -m
Now, go to the [timestamp].create_disneypluses_table.php file and add the columns.
public function up() { Schema::create('disneypluses', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('show_name'); $table->string('series'); $table->string('lead_actor'); $table->timestamps(); }); }
Now, migrate the database using the following command.
php artisan migrate
Step 5: Create a controller and routes
The next step is to create a DisneyplusController.php file.
php artisan make:controller DisneyplusController
Now, add the two routes inside the routes >> web.php file.
// web.php Route::get('disneyplus', 'DisneyplusController@create')->name('disneyplus.create'); Route::post('disneyplus', 'DisneyplusController@store')->name('disneyplus.store');
Now, create two methods inside the DisneyplusController.php file.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Disneyplus; use PDF; class DisneyplusController extends Controller { public function create() { } public function store() { } }
Remember to import the PDF module by using PDF; code.
Step: 6 Create a form blade file for input the data
Now, inside the views folder, create the form.blade.php file. Add the following code.
@extends('layout') @section('content') <style> .uper { margin-top: 40px; } </style> <div class="card uper"> <div class="card-header"> Add Disneyplus Shows </div> <div class="card-body"> @if ($errors->any()) <div class="alert alert-danger"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div><br /> @endif <form method="post" action="{{ route('disneyplus.store') }}"> <div class="form-group"> @csrf <label for="name">Show Name:</label> <input type="text" class="form-control" name="show_name"/> </div> <div class="form-group"> <label for="price">Series :</label> <input type="text" class="form-control" name="series"/> </div> <div class="form-group"> <label for="quantity">Show Lead Actor :</label> <input type="text" class="form-control" name="lead_actor"/> </div> <button type="submit" class="btn btn-primary">Create Show</button> </form> </div> </div> @endsection
Step 7: Store data in the database
Now, we will write the two functions inside the DisneyplusController.php file.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Disneyplus; class DisneyplusController extends Controller { public function create() { return view('form'); } public function store(Request $request) { $validatedData = $request->validate([ 'show_name' => 'required|max:255', 'series' => 'required|max:255', 'lead_actor' => 'required|max:255', ]); Disneyplus::create($validatedData); return redirect('/disneyplus')->with('success', 'Disney Plus Show is successfully saved'); } }
So, in the above file, first, we have shown the form file, and then inside the store function, we check for validation and then store the data into the database.
Also, add the fillable fields inside the Disneyplus.php model file.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Disneyplus extends Model { protected $fillable = ['show_name', 'series', 'lead_actor']; }
Now, go to this route: http://laravel6.test/disneyplus or http://localhost:8000/disneyplus.
You will see one form. Try to save the data, and if everything in the code is right, you will see one entry in the database.
Step: 8 Create a view file to display the data.
Before creating a view file, we need to add one route inside the web.php.
// web.php Route::get('disneyplus/list', 'DisneyplusController@index')->name('disneyplus.index');
Now, create a view file called list.blade.php file. Add the following code.
@extends('layout') @section('content') <table class="table table-striped"> <thead> <th>ID</th> <th>Show Name</th> <th>Series</th> <th>Lead Actor</th> <th>Action</th> </thead> <tbody> @foreach($shows as $show) <tr> <td>{{$show->id}}</td> <td>{{$show->show_name}}</td> <td>{{$show->series}}</td> <td>{{$show->lead_actor}}</td> </tr> @endforeach </tbody> </table> @endsection
Now, add the code inside the index() function of the DisneyplusController.php file.
public function index() { $shows = Disneyplus::all(); return view('list', compact('shows')); }
Now, go to the http://laravel6.test/disneyplus/list or http://localhost:8000/disneyplus/list.
You will see the listing of the shows.
Step: 9 Create a route to download the pdf file
Add the following code inside the route file.
// web.php Route::get('/downloadPDF/{id}','DisneyplusController@downloadPDF');
Now, update the list.blade.php file and add the Download PDF link.
@extends('layout') @section('content') <table class="table table-striped"> <thead> <th>ID</th> <th>Show Name</th> <th>Series</th> <th>Lead Actor</th> <th>Action</th> </thead> <tbody> @foreach($shows as $show) <tr> <td>{{$show->id}}</td> <td>{{$show->show_name}}</td> <td>{{$show->series}}</td> <td>{{$show->lead_actor}}</td> <td><a href="{{action('DisneyplusController@downloadPDF', $show->id)}}">Download PDF</a></td> </tr> @endforeach </tbody> </table> @endsection
Step: 10 Create pdf.blade.php file to design our pdf
You can create the new DOMPDF instance and load an HTML string, file, or blade view name. You can save it to the file or stream.
Okay, inside the views folder, create one file called pdf.blade.php file and add the following code.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <table class="table table-bordered"> <thead> <tr> <td><b>Show Name</b></td> <td><b>Series</b></td> <td><b>Lead Actor</b></td> </tr> </thead> <tbody> <tr> <td> {{$show->show_name}} </td> <td> {{$show->series}} </td> <td> {{$show->lead_actor}} </td> </tr> </tbody> </table> </body> </html>
We have created a simple table that will be generated inside the PDF.
Step: 11 Write a controller function to download the PDF
Write the following code inside the DisneyplusController.php file.
// DisneyplusController.php public function downloadPDF($id) { $show = Disneyplus::find($id); $pdf = PDF::loadView('pdf', compact('show')); return $pdf->download('disney.pdf'); }
Now, go to the http://laravel6.test/disneyplus/list or http://localhost:8000/disneyplus/list and click on the Download PDF link.
You will see that it downloads the PDF file and opens it; you will see the table containing show listings.
Conclusion
This was a simple example of Laravel PDF Generation. Finally, our tutorial on How to Generate PDF in Laravel 8 is over.
Great tutorial thanks!!
could it generate pdf out of tables and images?
here i am facing some problem when i am trying to use external css. can you help me how can i solve this problem?
Not working only page infinity loading but nothing else
Non-static method Barryvdh\DomPDF\PDF::loadView() should not be called statically
Hi Krunal, great tutorial!!
I´m just starting with Laravel and this was a super useful explanation
to me.
Thanks and keep helping people to leverage knowledge on this great framework
People like you make a great difference
Cheers
Mauricio
Thank for sharing keep continue…. Good luck
Well Done, Krunal! This was a very helpful tutorial.
Two small suggestions:
1. Why not include the “use PDF; ” directive in your DisneyplusController script, rather than as a sidenote?
2. It would save a few keystrokes to use “php artisan make:controller DisneyplusController -r” and lete the system insert the index, store and create functions.
its giv an error
Error : failed to open stream: No such file or directory in file
it is work
Hi Kunal,
could you please make a tutorial about creating a PDF with multiple pages?
Thanks!
Illegal string offset ‘hex’ this error occurred while create pdf file