Create a PDF in PHP using domPDF

domPDF is a PHP library to convert HTML to PDF. It comes with many features like support for images including basic support for svg images, CSS2 support and some properties from CSS3.

Create a PDF in PHP using domPDF

Why domPDF to convert HTML to PDF? Well domPDF has a HTML layout rendering engine written in PHP with support of many features like CSS2 and CSS3, Images, Loading of external stylesheets. Which means developers can easily create a PDF without needing to go through traditional PDF library's documentation get familiar with it. So you will need to either download domPDF stable version Dompdf 3.0.0 or download it via composer.

composer require dompdf/dompdf

domPDF Features:

  • Supports most CSS 2.1 and a few CSS3 properties.
  • Supports most presentational HTML 4.0 attributes.
  • Supports external stylesheets.
  • Supports complex tables, including row & column spans, separate & collapsed border models, individual cell styling
  • Image support
  • Basic SVG support with some limitations.

Requirements:

  • PHP version 7.1 or higher
  • DOM extension
  • MBString extension
  • php-font-lib
  • php-svg-lib

We will be converting a demo curriculum vitae and files we are going to create are:

  • index.php: which contains front code to call an action for download.
  • download-pdf.php: which actually contains the html that we are going convert to pdf.
  • style.css: contains styles for the html file.

index.php

<!DOCTYPE html>
<html>
<head>
<title>Create PDF in PHP using DomPDF - Demo</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<style>
*{
box-sizing: border-box;
}
html,body{
margin: 0;
padding: 0;
}
body{
background-color: #f6f6f6;
font-family: "Segoe UI", "Roboto", "Helvetica", sans-serif;
font-size: 15px;
font-weight: normal;
font-style: normal;
}
a{
text-decoration: none;
color: #3778cd;
}
.container{
max-width: 1140px;
width: 100%;
margin-right: auto;
margin-left: auto;
padding-right: 15px;
padding-left: 15px;
}
.py-4{
padding-top: 1rem;
padding-bottom: 1rem;
}
.btn{
display: inline-block;
padding: 5px 10px;
cursor: pointer;
font: inherit;
}
.btn-green{
background: #009549;
border: 1px solid #009549;
color: #fff;
}
</style>
</head>
<body>
<div class="container">
<div class="py-4">
<a href="download-pdf.php" type="button" class="btn btn-green">Download PDF</a>
</div>
</div>
</body>
</html>

download-pdf.php

<?php 
ob_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="<?=BASE_URL?>/create-pdf-in-php-using-dompdf/css/style.css" rel="stylesheet" />
</head>
<body>
<main class="main">
<div class="head">
<div class="image">
<img src="<?=BASE_URL?>/create-pdf-in-php-using-dompdf/images/avatar.png" />
</div>
<div class="title">
<h3>John Doe</h3>
<h4>Curriculum Vitae</h4>
</div>
</div>
<div style="float:none;clear:both;"></div>
<div class="column-container">
<div class="column-left">
<div class="info-box">
<div class="box-heading">
Contact Info
</div>
<div class="box-content">
<ul>
<li>
<span class="fa-icon">&#xf095;</span>
+1-555-6666
</li>
<li>
<span class="fa-icon">&#xf0e0;</span>
[email protected]
</li>
<li>
<span class="fa-icon">&#xf08e;</span>
www.website.com
</li>
<li>
<span class="fa-icon">&#xf041;</span>
Street No, City, Country
</li>
</ul>
</div>
</div>

<div class="info-box">
<div class="box-heading">
Languages
</div>
<div class="box-content">
<ul>
<li>
<div class="skill-box">
<span>English</span>
<div class="progress">
<div class="level" style="width: 70%;"></div>
</div>
</div>
</li>
<li>
<div class="skill-box">
<span>French</span>
<div class="progress">
<div class="level" style="width: 55%;"></div>
</div>
</div>
</li>
<li>
<div class="skill-box">
<span>Russian</span>
<div class="progress">
<div class="level" style="width: 45%;"></div>
</div>
</div>
</li>
<li>
<div class="skill-box">
<span>German</span>
<div class="progress">
<div class="level" style="width: 40%;"></div>
</div>
</div>
</li>
</ul>
</div>
</div>

<div class="info-box">
<div class="box-heading">
Skills
</div>
<div class="box-content">
<ul>
<li>
<div class="skill-box">
<span>Communication</span>
<div class="progress">
<div class="level" style="width: 80%;"></div>
</div>
</div>
</li>
<li>
<div class="skill-box">
<span>Adaptibility</span>
<div class="progress">
<div class="level" style="width: 75%;"></div>
</div>
</div>
</li>
<li>
<div class="skill-box">
<span>Self Motivation</span>
<div class="progress">
<div class="level" style="width: 85%;"></div>
</div>
</div>
</li>
<li>
<div class="skill-box">
<span>TeamWork</span>
<div class="progress">
<div class="level" style="width: 95%;"></div>
</div>
</div>
</li>
<li>
<div class="skill-box">
<span>Time Management</span>
<div class="progress">
<div class="level" style="width: 98%;"></div>
</div>
</div>
</li>
</ul>
</div>
</div>

<div class="info-box">
<div class="box-heading">
Introduction
</div>
<div class="box-content introduction">
Donec ornare facilisis commodo. Duis blandit lacinia velit, a gravida mi efficitur non.
Mauris hendrerit sodales dolor a tincidunt. Vestibulum auctor libero consectetur dictum rutrum.
Suspendisse potenti. Vivamus iaculis eget sem vel venenatis. Sed gravida porta viverra
</div>
</div>
</div>

<div class="column-right">
<div class="info-box">
<div class="box-heading">
Experiences
</div>
<div class="box-content">
<div class="experience-box">
<div class="experience-heading">Account Manager</div>
<div class="experience-duration">Lorem Ipsum | 2015-Present</div>
<div class="experience-details">
Sed lorem ligula, pharetra eget purus a, tincidunt consequat diam.
Maecenas laoreet, dolor id rutrum consequat, nisl lorem aliquet sem, id lacinia arcu tellus sed purus.
Curabitur venenatis nulla sed risus consequat, a lacinia ante hendrerit.
</div>
</div>

<div class="experience-box">
<div class="experience-heading">Sales Exective</div>
<div class="experience-duration">Lorem Ipsum | 2013-2015</div>
<div class="experience-details">
Quisque dictum feugiat odio ac eleifend. Integer eleifend sit amet ex et posuere.
Phasellus id ultricies magna. Suspendisse consequat vitae leo accumsan lobortis.
Duis ut sodales dolor. Aliquam massa ex, ultricies id imperdiet quis, ultricies ac sem.
</div>
</div>

<div class="experience-box">
<div class="experience-heading">Sales Assistant</div>
<div class="experience-duration">Lorem Ipsum | 2010-2013</div>
<div class="experience-details">
Integer id gravida enim, luctus iaculis nunc. Vestibulum porttitor massa non tortor commodo scelerisque.
Maecenas massa tellus, scelerisque vitae venenatis quis, ultricies id orci.
Etiam volutpat odio vitae suscipit suscipit. Nam malesuada ex at porttitor auctor.
</div>
</div>
</div>
</div>
<div class="info-box">
<div class="box-heading">
Education & Courses
</div>
<div class="box-content">
<div class="education-block-left">
<div class="title">University of Glosgow</div>
<div class="education-details">PHD - Business & Finance | 2005</div>
<div class="education-comments">Extra comments about education</div>
</div>
<div class="education-block-right">
<div class="title">University of New York</div>
<div class="education-details">MBA - Business & Finance | 2005</div>
<div class="education-comments">Extra comments about education</div>
</div>
<div style="float:none;clear:both;"></div>
</div>
</div>
</div>
</div>
</main>
</body>
</html>
<?php

$html = ob_get_contents();
ob_end_clean();

// If downloaded via composer
//require 'vendor/autoload.php';

// If downloaded package archive
require 'dompdf/autoload.inc.php';

use Dompdf\Dompdf;

$context = stream_context_create([
'ssl' => [
'verify_peer' => FALSE,
'verify_peer_name' => FALSE,
'allow_self_signed'=> TRUE
]
]);

$dompdf = new Dompdf([
'is_remote_enabled' => true,
'is_html5_parser_enabled' => true
]);

$dompdf->setHttpContext($context);

$dompdf->setPaper('A4');
$dompdf->loadHtml($html);

$dompdf->render();
$dompdf->stream('sample-pdf', ['attachment' => true]);

style.css

@page {
size: A4 portrait;
margin: 20px !important;
}
*{
box-sizing: border-box;
}
html, body {
margin:0;
padding: 0;
width: 794px;
font-family: Helvetica, serif;
font-size: 14px;
}
.clearfix{
float:none;
clear:both;
}
.fa-icon{
font-family: FontAwesome, serif;
width: 20px;
display: inline-block;
margin-top: 5px;
}
.head{
height: 150px;
margin-bottom: 20px;
}
.head .image,
.head .title{
width: 150px;
float: left;
text-align: center;
letter-spacing:5px;
text-transform: uppercase;
position: relative;
z-index: 2;
}
.head .image{
z-index: 5;
}
.head .image img{
border-radius: 70px;
height: 140px;
width: 140px;
margin: 5px;
}
.head .title{
background: #e28b01;
width: 754px;
height: 150px;
border-radius: 70px;
margin-left: -150px;
}
.head .title h3{
font-size: 25px;
}
.column-container{
height: 800px;
}
.column-left, .column-right{
width: 275px;
float: left;
}
.column-right{
width:459px;
padding-left: 20px;
}

.box-heading {
background: #4F4F4F;
color: #fff;
padding: 10px;
font-weight: bold;
text-transform: uppercase;
}
.box-content {
padding: 10px;
margin-bottom: 20px;
}
ul{
margin: 0;
padding: 0;
list-style: none;
}
ul li{
padding: 3px 0;
}
.skill-box span{
width: 120px;
display: inline-block;
margin-right: 10px;
}
.skill-box .progress{
display: inline-block;
height: 10px;
background: #ddd;
width: 115px;
}
.skill-box .progress .level{
background: #e28b01;
height: 10px;
}
.introduction{
text-align: justify;
}
.experience-heading,
.experience-duration{
font-weight: bold;
text-align: center;
margin-bottom: 10px;
}
.experience-duration{
color: #888;
}
.experience-details{
margin-bottom: 15px;
text-align: justify;
}
.education-block-left{
width: 50%;
float: left;
}
.education-block-right{
width: 50%;
float: right;
}
.education-block-left > div,
.education-block-right > div{
padding: 2px 8px;
}
.title{
font-weight: bold;
}
.education-details{
font-style: italic;
}
.education-comments{
color: #888;
font-size: 12px;
}