Chapter 11. PDF

Adobe’s Portable Document Format (PDF) is a popular way to get a consistent look, both on screen and in print, for documents. This chapter shows you how to dynamically create PDF files with text, graphics, links, and more. Doing so opens the door to many applications. You can create almost any kind of business document, including form letters, invoices, and receipts. In addition, you can automate most paperwork by overlaying text onto a scan of the paper form and saving the result as a PDF file.

PDF Extensions

PHP has several libraries for generating PDF documents. This chapter’s examples use the popular FPDF library (http://www.fpdf.org), a set of PHP code you include in your scripts with the require() function—it doesn’t require any server-side configuration or support, so you can use it even without support from your host. The basic concepts, structure, and features of a PDF file should be common to all the PDF libraries, however.

Note

Another PDF-generating library, TCPDF (https://tcpdf.org/), is better at handling HTML special characters and UTF-8 multilanguage output than FPDF. Look it up if you need that capability. The methods you’ll use are writeHTMLCell() and writeHTML().

Documents and Pages

A PDF document is made up of a number of pages, each of which contains text and/or images. This section shows you how to create a document, add pages in that document, write text to the pages, and send the pages back to the browser when you’re done.

Note

The examples in this chapter assume that you have at least the Adobe PDF document viewer installed as an add-on to your web browser. These examples will not work otherwise. You can get the add-on from the Adobe website (https://helpx.adobe.com/acrobat/using/display-pdf-in-browser.html).

A Simple Example

Let’s start with a simple PDF document. Example 11-1 writes the text “Hello Out There!” to a page and then displays the resulting PDF document.

Example 11-1. “Hello Out There!” in PDF
<?php

require("../fpdf/fpdf.php"); // path to fpdf.php

$pdf = new FPDF();
$pdf->addPage();

$pdf->setFont("Arial", 'B', 16);
$pdf->cell(40, 10, "Hello Out There!");

$pdf->output();

Example 11-1 follows the basic steps involved in creating a PDF document: creating a new PDF object instance, creating a page, setting a valid font for the PDF text, and writing the text to a “cell” on the page. Figure 11-1 shows the output of Example 11-1.

“Hello Out There!” PDF example
Figure 11-1. “Hello Out There!” PDF example

Initializing the Document

In Example 11-1, we started by making a reference to the FPDF library with the require() function. Then the code created a new instance of the FPDF object. Note that all the calls to the new FPDF instance are object-oriented calls to methods in that object. (Refer to Chapter 6 if you have trouble with the examples in this chapter.) After you have created the new instance of the FPDF object, you’ll need to add at least one page to the object, so the AddPage() method is called. Next, you need to set the font for the output you are about to generate with the SetFont() call. Then, using the cell() method call, you can send the output to your created document. To send all your work to the browser, simply use the output() method.

Outputting Basic Text Cells

In the FPDF library, a cell is a rectangular area on the page that you can create and control. This cell can have a height, width, and border, and of course it can contain text. The basic syntax for the cell() method is as follows:

cell(float w [, float h [, string txt [, mixed border
 [, int ln [, string align [, int fill [, mixed link]]]]]]])

The first option is the width, then the height, and then the text to be output. This is followed by the border, the new line control, its alignment, any fill color for the text, and finally whether you want the text to be an HTML link. So, for example, if we want to change our original example to have a border and be center-aligned, we would change the cell code to the following:

$pdf->cell(90, 10, "Hello Out There!", 1, 0, 'C');

You’ll use the cell() method extensively when generating PDF documents with FPDF, so you’d be well served by taking some time to learn the ins and outs of this method. We will cover most of them in this chapter.

Text

Text is the heart of a PDF file. Accordingly, there are many options for changing its appearance and layout. In this section, we’ll discuss the coordinate system used in PDF documents, functions for inserting text and changing text attributes, and font usage.

Coordinates

The origin (0, 0) in a PDF document with the FPDF library is in the top-left corner of the defined page. All of the measurements are specified in points, millimeters, inches, or centimeters. A point (the default) is equal to 1/72 of an inch, or 0.35 mm. In Example 11-2, we change the defaults of the page dimensions to inches with the FPDF() class instantiation-constructor method. The other options with this call are the orientation of the page (portrait or landscape) and the page size (typically Legal or Letter). The full options of this instantiation are shown in Table 11-1.

Table 11-1. FPDF options
FPDF() constructor parameters Parameter options
Orientation P (portrait; default)
L (landscape)
Units of measurement pt (point, or 1/72 of an inch; default)
in (inch)
mm (millimeter)
cm (centimeter)
Page size Letter (default)
Legal
A5
A3
A4 or a customizable size (see FPDF documentation)

Also in Example 11-2, we use the ln() method call to manage what line of the page we are on. The ln() method can take an optional argument instructing it how many units (i.e., the unit of measurement defined in the constructor call) to move. In our case, we’ve defined the page to be in inches, so we’re moving through the document in measurement units of inches. Further, since we’ve defined the page to be in inches, the coordinates for the cell() method are also rendered in inches.

Note

This is not really the ideal approach for building a PDF page because you don’t have as fine-grained control with inches as you would with points or millimeters. We’ve used inches in this instance so that the examples can be seen more clearly.

Example 11-2 puts text in the corners and center of a page.

Example 11-2. Demonstrating coordinates and line management
<?php
require("../fpdf/fpdf.php");

$pdf = new FPDF('P', 'in', 'Letter');
$pdf->addPage();

$pdf->setFont('Arial', 'B', 24);

$pdf->cell(0, 0, "Top Left!", 0, 1, 'L');
$pdf->cell(6, 0.5, "Top Right!", 1, 0, 'R');
$pdf->ln(4.5);

$pdf->cell(0, 0, "This is the middle!", 0, 0, 'C');
$pdf->ln(5.3);

$pdf->cell(0, 0, "Bottom Left!", 0, 0, 'L');
$pdf->cell(0, 0, "Bottom Right!", 0, 0, 'R');

$pdf->output();

The output of Example 11-2 is shown in Figure 11-2.

Coordinate and line control demo output
Figure 11-2. Coordinate and line control demo output

So let’s analyze this code a little. After we define the page with the constructor, we see these lines of code:

$pdf->cell(0, 0, "Top Left!", 0, 1, 'L');
$pdf->cell(6, 0.5, "Top Right!", 1, 0, 'R');
$pdf->ln(4.5);

The first cell() method call tells the PDF class to start at the top coordinates (0,0) and write out the left-justified text “Top Left!” with no border, and to insert a line break at the end of the output. The next cell() method call prompts the creation of a cell six inches wide, again starting on the lefthand side of the page, with a half-inch-high border and the right-justified text “Top Right!” We then tell the PDF class to move down 4½ inches on the page with the ln(4.5) statement, and continue the output generation from that point. As you can see, there are a lot of possible combinations with the cell() and ln() methods alone. But that is not all that the FPDF library can do.

Text Attributes

There are three common ways to alter the appearance of text: bold, underline, and italics. In Example 10-3 the SetFont() method (introduced earlier in the chapter) is used to alter the formatting of the outgoing text. Note that these alterations in the text’s appearance are not exclusive (i.e., you can use them in any combination) and that the font name is changed in the last SetFont() call.

Example 11-3. Demonstrating font attributes
<?php
require("../fpdf/fpdf.php");

$pdf = new FPDF();
$pdf->addPage();

$pdf->setFont("Arial", '', 12);
$pdf->cell(0, 5, "Regular normal Arial Text here, size 12", 0, 1, 'L');
$pdf->ln();

$pdf->setFont("Arial", 'IBU', 20);
$pdf->cell(0, 15, "This is Bold, Underlined, Italicised Text size 20", 0, 0, 'L');
$pdf->ln();

$pdf->setFont("Times", 'IU', 15);
$pdf->cell(0, 5, "This is Underlined Italicised 15pt Times", 0, 0, 'L');

$pdf->output();

Also, in this code the constructor has been called with no attributes passed into it, using the default values of portrait, points, and letter. The output of Example 11-3 is shown in Figure 11-3.

Changing font types, sizes, and attributes
Figure 11-3. Changing font types, sizes, and attributes

The available font styles that come with FPDF are:

  • Courier (fixed-width)

  • Helvetica or Arial (synonymous; sans serif)

  • Times (serif)

  • Symbol (symbols)

  • ZapfDingbats (symbols)

You can include any other font family for which you have the definition file by using the AddFont() method.

Of course, this wouldn’t be any fun at all if you couldn’t change the color of the text that you’re outputting to the PDF definition. Enter the SetTextColor() method. This method takes the existing font definition and simply changes the color of the text. Be sure to call this method before you use the cell() method so that the content of the cell can be changed. The color parameters are combinations of red, green, and blue numeric constants from 0 (none) to 255 (full color). If you do not pass in the second and third parameters, then the first number will be a shade of gray with red, green, and blue values equal to the single passed value. Example 11-4 shows how this can be employed.

Example 11-4. Demonstrating color attributes
<?php
require("../fpdf/fpdf.php");

$pdf = new FPDF();
$pdf->addPage();

$pdf->setFont("Times", 'U', 15);
$pdf->setTextColor(128);
$pdf->cell(0, 5, "Times font, Underlined and shade of Grey Text", 0, 0, 'L');
$pdf->ln(6);

$pdf->setTextColor(255, 0, 0);
$pdf->cell(0, 5, "Times font, Underlined and Red Text", 0, 0, 'L');

$pdf->output();

Figure 11-4 is the result of the code in Example 11-4.

Adding color to the text output
Figure 11-4. Adding color to the text output

Page Headers, Footers, and Class Extension

So far we’ve looked only at what can be output to the PDF page in small quantities. We did this intentionally, to show you the variety of what you can do within a controlled environment. Now we need to expand what the FPDF library can do. Remember that this library actually is just a class definition provided for your use and extension, the latter of which we’ll look at now. Since FPDF is indeed a class definition, all we have to do to extend it is to use the object command that is native to PHP, like this:

class MyPDF extends FPDF

Here we take the FPDF class and extend it with a new name of MyPDF. Then we can extend any of the methods in the object. We can even add more methods to our class extension if we so desire, but more on that later. The first two methods that we’ll look at are extensions of existing empty methods that are predefined in the parent of the FPDF class: header() and footer(). These methods, as their names imply, generate page headers and footers for each page in your PDF document. Example 11-5, which is rather long, shows the definition of these two methods. You will notice only a few newly used methods; the most significant is AliasNbPages(), which is used simply to track the overall page count in the PDF document before it is sent to the browser.

Example 11-5. Defining header and footer methods
<?php
require("../fpdf/fpdf.php");

class MyPDF extends FPDF
{
 function header()
 {
 global $title;

 $this->setFont("Times", '', 12);
 $this->setDrawColor(0, 0, 180);
 $this->setFillColor(230, 0, 230);
 $this->setTextColor(0, 0, 255);
 $this->setLineWidth(1);

 $width = $this->getStringWidth($title) + 150;
 $this->cell($width, 9, $title, 1, 1, 'C', 1);
 $this->ln(10);
 }

 function footer()
 {
 //Position at 1.5 cm from bottom
 $this->setY(-15);
 $this->setFont("Arial", 'I', 8);
 $this->cell(0, 10,
 "This is the page footer -> Page {$this->pageNo()}/{nb}", 0, 0, 'C');
 }
}

$title = "FPDF Library Page Header";

$pdf = new MyPDF('P', 'mm', 'Letter');
$pdf->aliasNbPages();
$pdf->addPage();

$pdf->setFont("Times", '', 24);
$pdf->cell(0, 0, "some text at the top of the page", 0, 0, 'L');
$pdf->ln(225);

$pdf->cell(0, 0, "More text toward the bottom", 0, 0, 'C');

$pdf->addPage();
$pdf->setFont("Arial", 'B', 15);

$pdf->cell(0, 0, "Top of page 2 after header", 0, 1, 'C');

$pdf->output();

The results of Example 11-5 are shown in Figure 11-5. This is a shot of both pages side by side to show you the page count in the footers and the page number at the top of the page(s) after page 1. The header has a cell with some coloring (for cosmetic effect); of course, you don’t have to use colors if you don’t want to.

Tables and Data

So far we’ve looked only at PDF materials that are static in nature. But PHP, being what it is, does so much more than static processes. In this section, we’ll combine some data from a database (using a MySQL example of the database information from Chapter 9) and FPDF’s ability to generate tables.

Note

Be sure to reference the database file structures available in Chapter 9 to follow along in this section.

Example 11-7 is, again, a little lengthy. However, it is well commented, so read through it here first; we’ll cover the highlights after the listing.

Example 11-7. Generating a table
<?php
require("../fpdf/fpdf.php");

class TablePDF extends FPDF
{
 function buildTable($header, $data)
 {
 $this->setFillColor(255, 0, 0);
 $this->setTextColor(255);
 $this->setDrawColor(128, 0, 0);
 $this->setLineWidth(0.3);
 $this->setFont('', 'B');
 
//Header
// make an array for the column widths
 $widths = array(85, 40, 15);
// send the headers to the PDF document
 for($i = 0; $i < count($header); $i++) {
 $this->cell($widths[$i], 7, $header[$i], 1, 0, 'C', 1);
 }
 
 $this->ln();
 
// Color and font restoration
 $this->setFillColor(175);
 $this->setTextColor(0);
 $this->setFont('');
 
// now spool out the data from the $data array
 $fill = 0;// used to alternate row color backgrounds
 $url = "http://www.oreilly.com";
 
 foreach($data as $row)
 {
 $this->cell($widths[0], 6, $row[0], 'LR', 0, 'L', $fill);
 
// set colors to show a URL style link
 $this->setTextColor(0, 0, 255);
 $this->setFont('', 'U');
 $this->cell($widths[1], 6, $row[1], 'LR', 0, 'L', $fill, $url);
 
// resore normal color settings
 $this->setTextColor(0);
 $this->setFont('');
 $this->cell($widths[2], 6, $row[2], 'LR', 0, 'C', $fill);
 
 $this->ln();
 
 $fill = ($fill) ? 0 : 1;
 }
 $this->cell(array_sum($widths), 0, '', 'T');
 }
}

//connect to database
$dbconn = new mysqli('localhost', 'dbusername', 'dbpassword', 'library');
$sql = "SELECT * FROM books ORDER BY title";
$result = $dbconn->query($sql);

// build the data array from the database records.
while ($row = $result->fetch_assoc()) {
 $data[] = array($row['title'], $row['ISBN'], $row['pub_year']);
}

// start and build the PDF document
$pdf = new TablePDF();

// Column titles
$header = array("Title", "ISBN", "Year");

$pdf->setFont("Arial", '', 14);

$pdf->addPage();
$pdf->buildTable($header, $data);

$pdf->output();

We are using the database connection and building two arrays to send to the buildTable() custom method of this extended class. Inside the buildTable() method, we set colors and font attributes for the table header. Then, we send out the headers based on the first passed-in array. There is another array called $width used to set the column widths in the calls to cell().

After the table header is sent out, we use the $data array containing the database information and walk through that array with a foreach loop. Notice here that the cell() method is using 'LR' for its border parameter. This inserts borders on the left and right of the cell in question, thus effectively adding the sides to the table rows. We also add a URL link to the second column just to show you that it can be done in concert with the table row construction. Lastly, we use a $fill variable to flip back and forth so that the background color will alternate as the table is built row by row.

The last call to the cell() method in this buildTable() method is used to draw the bottom of the table and close off the columns.

The result of this code is shown in Figure 11-9.

FPDF-generated table based on database information with active URL links
Figure 11-9. FPDF-generated table based on database information with active URL links

What’s Next

There are quite a few other features of FPDF that are not covered in this chapter. Be sure to go to the library’s website (http://www.fpdf.org) to see other examples of what it can help you accomplish. There are code snippets and fully functional scripts available there as well as a discussion forum—all designed to help you become an FPDF expert.

In the next chapter we’ll be switching gears a little to explore the interactions between PHP and XML. We will be covering some of the techniques that can be used to “consume” XML and how to parse it with a built-in library called SimpleXML.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset