How to use dompdf with css

I think its about time I create another tutorial on this awesome php library called dompdf.
For the sake of the innocent, dompdf is a php library used for generating… Surprise!
PDF documents using php.

So what the heck am I going to discuss in this article? What’s the relevance of this article?
To get you fired up, were going to create a sample page which has a sample table on it, then a print button and when the user clicks on it. A pdf file pops out of the browser.

So let’s go ahead and get started.

Requirements

  • Dompdf

Assumptions

I assume that you already know how to make use of css. Not the inline css, because that’s a thing of the past. I guess in the 90’s people used that. When I say css, were talking about this:

body{
   background-color:#CC10;
   font:14px Georgia, serif, calibri;
}

And this:

<link rel="stylesheet" href="external.css" type="text/css"/>

Oh,and definitely NOT this:

<th style="height:90px;">Some Header</th>

I also assume that you already know the basics of using dompdf, which I unfortunately tackled here:

How to use dompdf

Unfortunately because I believe that I had not explained the concept of output buffering and the whole dompdf thing in that article. So the article that you’re reading right now can be considered a remake. You can also visit the link above if you want.

And yes, I almost forgot that you must also know the basics of php and programming itself. Variables, echo, dollar signs, loops and every basic thing about php and programming that you can think of.

Procedure

First you have to prepare the table for all the food that were going to eat today.
Yup! I’m saying that you download dompdf, extract it, place it on a testing folder, then create 2 files.

  • One for viewing the output – this page will have the PRINT button on it.
  • Another for generating the pdf

After setting up all the necessary requirements…

Ooops, I guess that’s a little bit redundant, but never mind I’m a little energetic tonight(10:30pm) so please bear with me.
Go ahead and write your own css for the first page(view). But if you want to make your life easier, then just copy the one below.

<style type="text/css">
#btn_print{
	background:url(print.png) no-repeat;
	width:53px;
	height:23px;
	}
</style>

That’s an internal css. You can also make it external if you are the outgoing type.
And sorry if I disappointed you with that stylesheet. I just used it to put a background image on a link disguised as a button(don’t worry, you’ll know what I mean soon enough..)

Next, let’s create the array where we will fetch the data for our table later.

<?php
$x= array(array('name'=>'wern', 'age'=>10),array('name'=>'vongola','age'=>20),
array('name'=>'killua','age'=>30),array('name'=>'Lawliet','age'=>10),
array('name'=>'mikado ryugamine','age'=>15), array('name'=>'pikachu','age'=>50));
?>

When I make tutorials like this, I see to it that I don’t make much effort on naming things. Just like that $x variable. And all the names in the array are anime characters except the wern because that’s my name.

After that, start buffering the output. Any code whether html, php or css which comes after the code below are being stored somewhere I do not know. What’s important is that it is stored with all the format, the markup and everything.

<?php ob_start(); ?>

Then create the header for the table:

<tr>
     <th>Name</th>
     <th>Age</th>
</tr>

Yup, I didn’t include the table tag on purpose just to make sure that the output of those who just copy paste ain’t gonna work.

After that, go ahead and loop through the array that we created a while ago.

foreach($x as $y){
//output
}

That’s yet another incomplete code. Its just basic so go figure out how to do it before you continue.

Then call the ob_get_contents() function that’s built in to php. This function gets all the content that was stored in the ob_start() function. In other words, every single markup, css that came right after calling the ob_start() function. I still haven’t tested if this function also buffers the all the markups (html) that are enclosed in if or switch statement. You go try it out yourself and comment what you got in this post.

<?php
   $out = ob_get_contents();
   ob_end_flush();
?>

After that, you can put the buffered contents on a session array or a cookie. For this tutorial were going to make use of a session even if cookies sounds more delicious.

<?php
   $_SESSION['prints'] = array('table'=>$out);
?>

What we just did is to assign the $out variable which has all the buffered contents, into a session array item called ‘table’. Its important that you remember the name of the session because were going to need it later on. If you’ve not yet decided, the name of the session here is ‘prints’.

You can close the file that you’re working on for a while or just leave it as it is (if you’re not using notepad). Because were gonna work on the SECOND FILE now.

First, do the housekeeping:

require_once("dompdf/dompdf_config.inc.php");
$dompdf = new DOMPDF();

Include the dompdf class into your current file, then initialize the dompdf class by creating an object. The name of the object is not necessarily $dompdf, you can use $puke if you want. Ooops, sorry if you’re eating while reading this.

Then assign the contents of the table session to a variable.

$tbl = $_SESSION['prints']['table'];

Then buffer the current page:

<?php ob_start(); ?>

Put some css:

<style type="text/css">
* {
  margin:0; padding:0;
}
body{
  font:14px Georgia, serif;
}

#page-wrap{
  width:600px;
  margin: 0 auto;
}

table{
   border-collapse: collapse; width: 100%;
}

td{
   border:1px solid #ccc; padding:10px;
}

thead{
   width:100%;position:fixed;
   height:109px;
}
</style>

This really got me on my first try, I didn’t buffer the css along with the html, that’s why the output was a pure html pdf file. Oh and don’t get confuse with the pure html pdf file. It just means that it’s a pdf file without any styling or anything fancy formatting on it.

Then output the contents buffered from the first file that we created:

<?php
  echo $tbl;
?>

Finally, get the buffered contents again. It’s still the same markup we just added a css into it:

<?php
  $out = ob_get_contents();
  ob_end_flush();
?>

Don’t forget the ob_end_flush() function. If I’m not mistaken it’s the function that clears the cache for the output that has been buffered. We don’t need it since we already assigned it to the variable $out.

Okay, so here’s a little function that I created to generate pdf’s:

function generate_pdf($filename){
	global $dompdf;

	$dompdf->load_html(file_get_contents($filename));
	$dompdf->render();
	$dompdf->stream($filename. ".pdf", array("Attachment" => 0));
}

Remember that in every function, whether its  a function declared inside a class or just a plain function in your good old php written in procedural form. You always have to put the word global right before an object of a class. In this case the $dompdf object.

Finally, go ahead and do the last 2 steps. First, put the contents of the $out variable into a file called styled.html

file_put_contents('styled.html', $out);

After that, just call up the function that generates a pdf file from the html file that we just generated.

generate_pdf('styled.html');

Of course, you can be creative and put the current time as the suffix for the filename. But I’m not going to show it here since I also don’t know how to do that.

Shortcut

If you still haven’t noticed. We can actually strip down the process by directly converting the buffered contents into pdf. To cut things really short, here’s what you need in the most basic level:

<?php
require_once("dompdf/dompdf_config.inc.php");
$dompdf = new DOMPDF();
date_default_timezone_set('Asia/Manila');
$tym = date('g:i s');
$filename = 'print'.$tym;
$dompdf->load_html($_SESSION['prints']['table']);

$dompdf->render();
$dompdf->stream($filename. ".pdf", array("Attachment" => 0));
?>

The code above just showed you the answer for the question a while ago. Appending the current time to the filename of the pdf that will be generated.

We then loaded the html from the ‘prints’ session that we created a while ago.

Then we called the render() function from the dompdf class. This will render the html into pdf. By the time you call this function a pdf file already exist somewhere I don’t know, maybe the browser cache, a temporary folder in the server(wampserver if you’re on windows) or anywhere else.

Lastly, we called the stream() function. This will pop out the pdf file into the users face. It takes two arguments: the filename for the file, you also have to place the file extension which is pdf. The second argument is the option, the one above does not force the browser to open a download dialog box(I don’t know the actual name so bear with me). If you place 1 as the value for the attachment, it does the exact opposite.

Conclusion

That’s it! I guess this tutorial has already taken too long for you to be bored to death. As always, I hope that you learned something. Here’s a summary of what we did here:

  • Using output buffering in php
  • Generating html file from the data stored by the ob_start() function
  • Generating pdf from an html file
  • Generating pdf directly from the buffered output or html

Don’t forget to comment if you don’t understand something. Or if you have any suggestions.

6 thoughts on “How to use dompdf with css

  1. Excellent tutorial! Just got ahold of dompdf today, and have spent hours getting the finer points down as to how to do several different things with it. Visitors should remember that you also need your ‘html’ header before the ‘style’ tags, along with all the usual basics… (head, body). So… Inline CSS is from the 90’s hu?? Was that the LATE 90’s ?? 🙂 I would say that inline is great for changing specific common tags inside a page that are already set in the .css file for the rest of the website to be formatted some other way. Thanks Again!! 🙂

    • I assume that you already know how to fetch data from MySQL using PHP. The codes are the same to what I have in there all you have to do is to put the fetched data between ob_start() and ob_get_contents() like this:

  2. do me a favour. how can i display each row in a separate page. for ex., i have 6 rows, i need to display each row in separate new page. thnk in advance.

Leave a comment