Convert HTML to PDF in Laravel 9 with Dompdf Extension

This is a step by step Laravel tutorial about how to convert HTML to PDF within Laravel application using the Dompdf extension.

Data in the site is for users; we always want our site visitors to visualize the data adequately and efficiently. We are going to explain bit by bit to you on how to export to PDF doc format in Laravel.

Likewise, you will be able to generate PDF from HTML with the help of Dompdf plugin.

Dompdf is an outstanding HTML to PDF converter; It is a PHP based style-driven renderer exceptionally engineered for CSS 2.1 compliant HTML layout.

Not just that you can use it for representational purposes for HTML content and customize to a further extent, It can read external stylesheets, inline style tags, and the style attributes of individual HTML elements.

The Portable Document Format is a file format developed by Adobe in 1993 to present documents, including text formatting and images, in a manner independent of application software, hardware, and operating systems.
– wikipedia

We will create a laravel app, install and register Dompdf plugin, next create a table and add some dummy products data dynamically and export that tabular data into PDF file or document format.

Let’s start generating or converting HTML to PDF in Laravel.

Create Laravel App

Begin the first step with installing Laravel application.

composer create-project laravel/laravel laravel-html-to-pdf-example --prefer-dist

Get inside the project’s root:

cd laravel-html-to-pdf-example

Install Dompdf Package

Dompdf is a wrapper for HTML to PDF Converter, so we need to install Dompdf extension in Laravel application.

composer require barryvdh/laravel-dompdf

Set Up Dompdf Extension

Head over to config/app.php and place the DomPDF services in providers and aliases array.

...
...
...
'providers' => [
  Barryvdh\DomPDF\ServiceProvider::class,
],

'aliases' => [
  'PDF' => Barryvdh\DomPDF\Facade::class,
]
...
...
...

Following command creates a config file and the locus of the file is config/dompdf.php, and it allows you to define local configurations to get align with few settings.

php artisan vendor:publish

After running the above command you will have following options appeared on your terminal.

 Which provider or tag's files would you like to publish?:

  [0 ] Publish files from all providers and tags listed below
  [1 ] Provider: Barryvdh\DomPDF\ServiceProvider
  [2 ] Provider: Facade\Ignition\IgnitionServiceProvider
  [3 ] Provider: Fideloper\Proxy\TrustedProxyServiceProvider
  [4 ] Provider: Fruitcake\Cors\CorsServiceProvider
  [5 ] Provider: Illuminate\Foundation\Providers\FoundationServiceProvider
  [6 ] Provider: Illuminate\Mail\MailServiceProvider
  [7 ] Provider: Illuminate\Notifications\NotificationServiceProvider
  [8 ] Provider: Illuminate\Pagination\PaginationServiceProvider
  [9 ] Provider: Laravel\Tinker\TinkerServiceProvider
  [10] Tag: config
  [11] Tag: cors
  [12] Tag: flare-config
  [13] Tag: ignition-config
  [14] Tag: laravel-errors
  [15] Tag: laravel-mail
  [16] Tag: laravel-notifications
  [17] Tag: laravel-pagination

We need to type 1 in terminal and choose “Provider: Barryvdh\DomPDF\ServiceProvider” and hit enter.

Make Database Ready

Include database details in .env file:

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=root
DB_PASSWORD=

Model and Migrations

Next, we need to create a “Product” Model:

php artisan make:model Product -m

Open app/Product.php file, and place the following code.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;
    public $fillable = ['product_name', 'price', 'in_stock'];
}

Add table values in migration file, open database/migrations/timestamp_create_products_table.php file and place the given below code.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('product_name');
            $table->string('price');
            $table->string('in_stock');          
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Its time to migrate the table into the database.

php artisan migrate

Database setting in Laravel

Exporting HTML tabular data into PDF requires some data into the database, so move onto the PHPMyAdmin and run SQL query.

INSERT INTO `products` (`id`, `product_name`, `price`, `in_stock`) VALUES
(1, 'Clothes', '$100', 'Yes'),
(2, 'Jeans', '$150', 'Yes'),
(3, 'Sweater', '$50', 'Yes'),
(4, 'Hat', '$60', 'Yes'),
(5, 'Shoes', '$150', 'Yes'),
(6, 'Belt', '$70', 'Yes'),
(7, 'Party Dress', '$175', 'Yes'),
(8, 'Trouser', '$40', 'Yes');

Create Controller

Next, generate a controller using below composer command.

php artisan make:controller ProductController 

The ProductController class has two functions, the getProducts() function fetches the product data and binds it to view the exportPDF() function likewise let you export HTML to PDF not just that you can also download the PDF of tabular data.

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;

use PDF;

class ProductController extends Controller {
    // Show products
    public function getProducts(){
      $product = Product::all();
      return view('home', compact('product'));
    }

    // Export to PDF
    public function exportPDF() {
        
        $p = Product::all();

        view()->share('p', $p);
        $pdf_doc = PDF::loadView('export_pdf', $p);

        return $pdf_doc->download('pdf.pdf');
    }    
}

Setting Up Routes

Use ProductController at the top, define two routes the first route gets the products from the database and second route creates HTML to PDF.

Add the code in routes/web.php file.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('home', [ProductController::class, 'getProducts']);

Route::get('/products/create-pdf', [ProductController::class, 'exportPDF']);

Create View

Head over to resources/views folder, create home.blade.php file, this file will display products data in table with the help of Bootstrap UI.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel 8 HTML to PDF Demo</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
</head>

<body class="antialiased container mt-5">

    <div class="d-flex flex-row-reverse bd-highlight mb-3">
        <a class="btn btn-success" href="{{ URL::to('/products/create-pdf') }}">Download PDF</a>
    </div>

    <table class="table">
        <thead>
            <tr class="table-primary">
                <td>Product Name</td>
                <td>Price</td>
                <td>In Stock</td>
            </tr>
        </thead>
        <tbody>
            @foreach ($product as $item)
            <tr>
                <td>{{ $item->product_name }}</td>
                <td>{{ $item->price }}</td>
                <td>{{ $item->in_stock }}</td>
            </tr>
            @endforeach
        </tbody>
    </table>
</body>

</html>

Also, create export_pdf.blade.php in views folder, add the following code. This file will be the layout for HTML table of the PDF document.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel 8 HTML to PDF Example</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
</head>

<body class="antialiased container mt-5">

    <table class="table">
        <thead>
            <tr class="table-primary">
                <td>Product Name</td>
                <td>Price</td>
                <td>In Stock</td>
            </tr>
        </thead>
        <tbody>
            @foreach ($p as $data)
            <tr>
                <td>{{ $data->product_name }}</td>
                <td>{{ $data->price }}</td>
                <td>{{ $data->in_stock }}</td>
            </tr>
            @endforeach
        </tbody>
    </table>
</body>

</html>

Generate HTML to PDF in Laravel

Start the application using the given below command:

php artisan serve

Check the following URL:

http://127.0.0.1:8000/home

Summary

We have seen how to generate HTML to PDF in Laravel using Dompdf package; we converted HTML Table data into portable document format. I hope you will like this tutorial.

Download Code: GitHub