Creating PDFs from HTML and CSS with PHP and Dompdf
Php 17-Oct-2016

Creating PDFs from HTML and CSS with PHP and Dompdf

To start with, let us install Dompdf. The easiest way to add Dompdf to your project is to use Composer. To see how to install Composer, do follow https://getcomposer.org/download/. Once you have it on your machine, you can navigate to the directory where your web application is located (usually using the cd command) in your Command line/Terminal and type composer require dompdf/dompdf. This will install Dompdf and all you have to do is include it in your desired files and use it. Composer is a dependency manager similar to npmfor Node.js but for PHP and it is a good idea to use it. If you do not wish to use Composer, you can directly download the Dompdf library from https://github.com/dompdf/dompdf/releases and unzip it in your desired folder.

Once you have Dompdf, let us create a simple HTML template to show to the user as PDF. Below is a PHP file which serves for the template of the PDF. It is a dummy invoice for an online order. We expect an $order array which would contain the keys that will participate in the PDF – such as the name of the user, the name of the ordered product, its price, expected delivery date and so on. Then, the PHP script just displays some HTML and fills it with possibly dynamically-generated values related to the specific order. Notice that the template also loads an external stylesheet – Bootstrap and that we define a style tag (there is no need to place it in the head tag or create a head tag) that highlights the dynamically-generated values inside the invoice. The style tag also loads a custom font from Google Fonts which we will use for the invoice.

Pdf-template/template.php

<?php

if (!isset($order)) die();

?>

<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css'>

<style>

/* LOAD GOOGLE FONT */

/* latin-ext */

@font-face {

  font-family: 'Oxygen';

  font-style: normal;

  font-weight: 400;

src: local('Oxygen'), local('Oxygen-Regular'), url(https://fonts.gstatic.com/s/oxygen/v5/IIPDrwV5KNJo5-LaFlLy2fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');

unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;

}

/* latin */

@font-face {

  font-family: 'Oxygen';

  font-style: normal;

  font-weight: 400;

src: local('Oxygen'), local('Oxygen-Regular'), url(https://fonts.gstatic.com/s/oxygen/v5/78wGxsHfFBzG7bRkpfRnCQ.woff2) format('woff2');

unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;

}

* {

  font-family :"Oxygen" !important;

}

.order-detail {

  font-weight: bolder;

}

.name {

  text-transform: capitalize;

}

 

.product, .product-price {

  color: #35aa45;

}

</style>

<div class="container-fluid">

<div class='panel panel-success'>

<div class='panel-heading'>

      Thank you for your order <span class='order-detail name'><?phpecho $order['name']; ?></span>!

</div>

<div class='panel-body'>

<p class='lead'>You ordered <span class='order-detail product'><?php echo $order['productName'];?></span> valued at

<span class='order-detail product-price'><?php echo $order['productPrice'];?>$</span>.</p>

<hr>

<small>The expected delivery date of the product is <span class='order-detail delivery'><?php echo $order['deliveryDate'];?></span></small>

</div>

</div>

</div>

Then, to display the PDF to the user, we create an order array and fill with the values related to the order. Afterwards, we create the template by using output buffering to store the template’s contents in a variable.

Index.php

$order = array("name" => "Ivan Dimov", "productName" => "Waterproof portable speakers", "productPrice" => "20", "deliveryDate" => "2150");

ob_start();

require_once("pdf-template/template.php");

$template = ob_get_clean();

Then, we load our Composer dependencies (Composer creates a vendor folder with an autoload.php file which loads all libraries loaded with Composer when required)

Index.php

require_once("vendor/autoload.php");

If you did not use Composer, Dompdf has an autoloader itself and you would just have to use it instead. The require statement should be something like: require_once ‘dompdf/autoload.inc.php’;  but the path to Dompdf’sautoload.inc.php file may vary in your situation.

After we have loaded Dompdf, all we have to do is pass it the HTML template and display the PDF in the user’s browser. We initialize the Dompdf class, then we pass it the HTML template (the $template variable) and stream the PDF to the browser giving the PDF the name of invoice.pdf.

Index.php

use Dompdf\Dompdf;

$dompdf = new Dompdf();

$dompdf->loadHtml($template);

$dompdf->setPaper('A4', 'landscape');

$dompdf->render();

$dompdf->stream("invoice");

Now, whenever we access index.php, we will end up with a PDF that looks like this:

Creating PDFs from HTML screenshot1

If we want to save the PDF to the server for reference – we need only 1-2 more lines of code. We get a string with the contents of the PDF file using $dompdf->output(), save it in a variable or directly put it into a file with an arbitrary name.

Adding one line is sufficient to save the PDF on our server:

file_put_contents("pdfs/invoice-" . mt_rand(0,99999) . ".pdf",  $dompdf->output());

Although, you would want a strict naming convention and not naming your invoices based on randomness. Unless you are okay with PDFs being overwritten from time to time when chance brings the same numbers.

Creating PDFs from HTML screenshot2

I guess, that’s it. You can now generate cool PDFs without much effort, hopefully.