How to Generate PDF in Laravel with DomPDF

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 ScratchFor 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.

See also

Laravel Export

Laravel CRUD

Laravel Validation

12 thoughts on “How to Generate PDF in Laravel with DomPDF”

  1. 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

    Reply
  2. 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.

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.