Code

Randy Dustin. Web Developer.

Get Started generating PDF’s today! Part 3 – extending/reuse

August 25th, 2009

Extending FPDF

If you are new to FPDF you may want to start by reading Part 1: Installation and Part 2: Playing with the options.

We can extend the core FPDF library and set up some functions that we can reuse. For example, we want to present a report in a table. The table will need column headings so that we know what each column of data represents. We could build that into the file for this one report, but say we want another report, different heading names but the same basic structure. We can either replicate the entire file from the other report and change the heading values or we can extend FPDF and create a tableHeader function that accepts an array of heading values and creates the header on the fly. This approach will save us time as we add new reports.

//include the core fpdf library
include 'fpdf/fpdf.php';

//create our custom class
class Myfpdf extends FPDF
{
	//takes an array of values and prints them as text headers with a black border around each one
       function tableHeader($header)
	{
		foreach($header as $col)
		{
			$this->Cell(38,7,$col,1,0,'L',0);
		}
		$this->Ln();
	}
}

Now we want to use this to create a pdf. So in our index.php file we need to set up some values and generate the pdf.

//include our custom fpdf class
include 'my.fpdf.php';

//instantiate the class
$myFPDF = new Myfpdf();

//create the pdf
$myFPDF->AddPage();
$myFPDF->setTitle('Title');
$myFPDF->setFont('Arial', 'B', 15);

//set up the Header values and call it
$myFPDF->tableHeader(array('Header 1', 'Header 2', 'Header 3', 'Header 4'));

echo $myFPDF->Output('test_header.pdf','I');

There you have it, a reusable table head builder. Now you can use the same concept as above to output the table data.

Get Started generating PDF’s today! Part 2 – playing with the options

August 4th, 2009

If you haven’t read part 1 of the series, you might want to start there.

Options

Today we are going to talk about the options we have when creating a pdf with the FPDF library. We will cover:

  • Changing page orientation and size
  • Changing Font styles
  • Changing the size and style of text cells
  • The different options for saving the final product

Changing page orientation and size

When we initiate the FPDF class we can specify the page orientation, unit of measure and size. Page orientations options are: Landscape (L) and Portrait (P). Next we can set the unit of measure (used for everything except font sizes): Point (pt), Millimeter (mm), Centimeter (cm), and inch (in). To specify page size we have many options along with the ability to specify our own custom size. The options are: A3, A4, A5, Letter, and Legal.

So if we want to create a legal sized PDF in the landscape format, using millimeters as our unit of measure this is what it looks like:

$fpdf = new FPDF('L', 'mm', 'Legal');

Say we want a custom sized page, we need to specify the width and height in an array. The width and height values will use the specified unit of measure. Here is an example:

$fpdf = new FPDF('L', 'mm', array('250','400'));

Our page will be 250 millimeters wide and 400 millimeters high.

Changing font styles

Next we want to set the font and its styles. According to the FPDF website the standard fonts available are: Arial, Times, Courier, Symbol, and ZapfDingbats. We will use Times for this example. Now we can set the font style, the options include: Italic (I), Bold (B), or Regular (empty string). You can also specify a combination of these styles. We will use bold. Last, we want to set the font size (always in points). For this example we will set it at 22 points.

So, our example would look like this:

$fpdf->SetFont('Times','B',22);

Note: This can be used on a line by line basis to change the font in a pdf.

Changing the size and style of text cells

Now we need to write some text to our pdf. To do this we use the Cell function. There are a lot of options available when writing a text cell: Width, Height, text you want printed, border, where the current position should go after this cell, text alignment, whether the cell should have a background color or not, and a link for the text. For a complete list of the variables see the manual at fpdf.org. We want to output our name in text that is centered on the page, with no border and we want the cell to go to the next line after writing our name.

So, our example would look like this:

$fpdf->Cell(0,0,'Our Name',0,1,'C');

I have found it handy to have the cell page of the manual open for reference while building my pdfs. It helps me keep the options straight.

The different options for saving the final product

We’ve got our document ready and now we need to save it. We can specify the name for the file (I have found it best to specify a name without spaces such as file_name instead of file name) and the destination of the document. We have four destinations available: Inline (I) to the browser, Download (D) with the browser, Save (F) to a local file, and return the document as a String (S).

So, our example would look like this:

$fpdf->Output('file_name','D');

Note: I have found “D” to be the most consistent option across the different browsers.

This concludes our lesson for today. I hope this helps you get started playing with the options!

We will be continuing the series soon by extending FPDF to save us time.

Read Part 3 – Extending & Reuse

Get started generating PDF’s today! Part 1 – installation

July 28th, 2009

FPDF

FPDF describes itself as

FPDF is a PHP class which allows to generate PDF files with pure PHP, that is to say without using the PDFlib library. F from FPDF stands for Free: you may use it for any kind of usage and modify it to suit your needs.

Installation

  1. Download the library and place it in a directory accessible by your web server

    It generally makes sense to put it in an includes directory.

  2. Include it in your web application
    /* sample web app */
    //include the FPDF library
    require_once('includes/fpdf.php');
    
  3. Create the page
    //instantiate the object
    $fpdf = new FPDF();
    
    //create a page
    $fpdf->AddPage();
    
    //set the font, font-style, and size
    $fpdf->SetFont('Arial', 'B', 14);
    
    //create the text to be output and go to the next line
    $fpdf->Cell(22, 12, "Randy Dustin", 0,1);
    //the next line
    $fpdf->Cell(22, 12, "Pretty much the coolest person on Earth!");
    
    //create the page
    $fpdf->Output();
    

For more information and tutorials on building pdfs you can go to the FPDF website and reference their tutorials and the manual

We will be continuing this series soon with a closer look at our options when creating a page. Some things to look for are:

  • Changing page orientation and size
  • Changing Font styles
  • Changing the size and style of text cells
  • The different options for saving the final product

Read Part 2 – playing with the options

Miscellaneous Billing: eliminating errors & simplifying the interface

July 8th, 2009

Background

Miscellaneous Billing is used by many departments on Plymouth State’s campus to initiate charges to individuals. The charges can range from Health Services to Residence Hall Damages and are logged in an Oracle table to be accessed and processed by the Bursar.

The Problems

  1. The original system was built in Microsoft Access – having a separate application for each department. This was a maintenance nightmare.
  2. It was extremely easy to charge the wrong individual.
  3. Making adjustments/reversing charges was very complex and error prone.

Problems Solved!

  1. The original plan was to replace the Residential Life Misc Billing application with a web interface; however, when I approached ITS with the idea they asked me to write it to replace all departmental Misc Billing apps. My task was to create the User Interface (UI) that would be used across campus. Any changes that need to be made can be made in one place for all departments. Problem Solved!

  2. The Access version consisted of a form within a form. The outer form contained an alphabetical list of people and always defaulted to the first person on the list. The problem was that users often forgot to select the person they wanted and ended up billing the default person. If the mistake was noticed soon enough, the charge could be removed and re-entered for the correct person. If not, the wrong person could end up with a bill.

    I created the new interface so that the user can enter a student’s name or ID number and return the correct person (see Figure 1 below). Once the user has entered the person’s name the page returns a list of possible people with that name or ID. The user then clicks the correct person to continue the billing process (see Figure 2 below). Problem Solved!

    The search screen of the Misc Billing app

    Figure 1: The search screen of the Misc Billing app


    Figure 2: The results of the search - in this case the correct name was returned

    Figure 2: The results of the search - in this case the correct name was returned

  3. The old application only allowed the user to view one bill at a time which meant that the user had to click through each record to find the one they wanted to reverse. Also, the user had to check to see if the charge had been processed by the Bursar to determine how they needed to proceed. Problem Solved!

RD Menu: reducing report time from hours to minutes

May 25th, 2009

Background

The RD Menu generates housing reports for Residential Life staff. These reports provide a range of options from generating a complete roster of students in alpha order to finding housing information for individual students.

The Problem

The original menu was created in Microsoft Access approximately five years ago; however, many of the reports took more than 20 minutes to run and some took nearly all day. The housing coordinator found this delay especially frustrating because she depended on those reports to accurately assign student housing.

Problem Solved!

Although originally tasked with optimizing the SQL in Access to reduce report times, the minutes saved were not satisfactory enough. I suggested, as a test, to re-create a report as a web application to discover if we could reduce the time it took to generate reports more. Reports which took 15-20 minutes in Access became virtually instantaneous in the web interface. Problem Solved!

Hartman Union Building: re-design

May 23rd, 2009

Background

The Hartman Union Building (HUB) website was primarily designed to provide information about student organizations, upcoming events, and facility availability. The site was designed using bright colors that varied from section to section and fancy fonts.  This gave the site a fun, energetic feel.

Problem

Over the last couple of years Plymouth State University’s Web Administrator has been unifying the design of departmental websites as well as converting them to a content management system.   When it came time to convert the HUB website, the web administrator wanted the HUB website to have a unified design, while the HUB staff wanted to maintain the unique, “fun” feel of the site.  The web administrator allowed me some leeway in the re-design but required that I use the same colors and basic layout as other department sites.

Problem Solved!

What I came up with was a slightly “grunge” header with softened lines. I call them fuzzy lines.

Picture 1: The fuzzy edged, relaxed HUB design

Picture 1: The fuzzy edged, relaxed HUB design

Picture 2: The hard-edged design of other department websites

Picture 2: The hard-edged design of other department websites

Timeclock: using FPDF to generate timesheets

April 9th, 2009

Background

Read background information on the design of the timeclock system!

Single vs. Multiple timesheets

Since each student’s timesheet is formated the same way, whether it is generated as a single timesheet or as part of multiple timesheets, I developed a class to create the timesheets.

Figure 1: A sample timesheet

Figure 1: A sample timesheet

In the class is a function called outputPDF which accepts one argument: an array of the timesheet values. Inside the function we begin creating the page.

function outputFPdf($app_data)
{
	$app_data;
	ob_start();
	$output = null;
	$output .= $this->fpdf->SetFont('Arial','B',15);
	$output .= $this->fpdf->Cell(80);
	$output .= $this->fpdf->Cell(30,10,'Complete Payroll Report',0,0,'C');
	$output .= $this->fpdf->Ln(8);
			$output .= $this->fpdf->SetFont('Arial','',10);
	$output .= $this->fpdf->Cell('',10,"Name: ".$app_data['name'],0,0,'C');
	$output .= $this->fpdf->Ln(6);
        <---- edited for brevity ---->
	ob_clean();
	return $output;
}

Now that we’ve got the timesheet ready let’s create a function that determines the timesheet type.

function createPdf($app_data, $type, $begin, $end, $section=null)
	{

There are a few things we want to accomplish with this function.

  • include and instantiate the fpdf library
    include 'includes/fpdf.php';
    $this->fpdf = new fpdfHelper();
  • Call the FPDF page numbering function and create the first page:
    $this->fpdf->AliasNbPages();
    $this->fpdf->AddPage();
  • Set the page title:
    $this->fpdf->setTitle('Complete Payroll Report');
  • check to see if the type is single and if so, generate the timesheet:
    if($type == 'single')
    {
    	//set the begin period and end period dates
    	$app_data['begin_period'] = $begin;
    	$app_data['end_period'] = $end;
    	//create the timesheet
    	$data = $this->outputPdf($app_data);
    	//get the current date so we can put it in the file name of the timesheet
    	$date = date("m_d_Y");
    	//create the file name with the employee's name and the date
    	$name = $app_data['name']."_".$date.".pdf";
    	//send it to the browser
    	echo $this->fpdf->fpdfOutput($name, $destination = 'd');
    }
  • if the type isn’t single check to see if it is multiple and if so, generate the timesheets:
    elseif($type == 'multiple')
    {
    	//get the current date to use in the file name
    	$date = date("m_d_Y");
    	//do stuff to get all apps in pdf
    	$data = null; //create variable to hold the timesheets as we generate them
    	//loop through the data and create a timesheet for each employee
    	foreach ($app_data as $app)
    	{
    		//set up begin and end date variables for the pay period
    		$app['begin_period'] = $begin;
    		$app['end_period'] = $end;
    		//generate timesheet for the current employee and store it in the data variable
    		$data .= $this->outputPdf($app);
    		//create a new page
    		$data .= $this->fpdf->AddPage();
    	}
    	//create the file name and include the name of the department (section) in it
    	$name = "payroll_report_".$section."_".$date.".pdf";
    	//send it to the browser
    	echo $this->fpdf->fpdfOutput($name, $destination = 'd');
    }
    }

So all together it looks like this:

function createPdf($app_data, $type, $begin, $end, $section=null)
{
	include 'includes/fpdf.php';
	$this->fpdf = new fpdfHelper();

	$this->fpdf->AliasNbPages();
	$this->fpdf->AddPage();

	$this->fpdf->setTitle('Complete Payroll Report');

	if($type == 'single')
	{
		//set the begin period and end period dates
		$app_data['begin_period'] = $begin;
		$app_data['end_period'] = $end;
		//create the timesheet
		$data = $this->outputPdf($app_data);
		//get the current date so we can put it in the file name of the timesheet
		$date = date("m_d_Y");
		//create the file name with the employee's name and the date
		$name = $app_data['name']."_".$date.".pdf";
		//send it to the browser
		echo $this->fpdf->fpdfOutput($name, $destination = 'd');
	}
	elseif($type == 'multiple')
	{
		//get the current date to use in the file name
		$date = date("m_d_Y");
		//do stuff to get all apps in pdf
		$data = null; //create variable to hold the timesheets as we generate them
		//loop through the data and create a timesheet for each employee
		foreach ($app_data as $app)
		{
			//set up begin and end date variables for the pay period
			$app['begin_period'] = $begin;
			$app['end_period'] = $end;
			//generate timesheet for the current employee and store it in the data variable
			$data .= $this->outputPdf($app);
			//create a new page
			$data .= $this->fpdf->AddPage();
		}
		//create the file name and include the name of the department (section) in it
		$name = "payroll_report_".$section."_".$date.".pdf";
		//send it to the browser
		echo $this->fpdf->fpdfOutput($name, $destination = 'd');
	}
}

Spring Housing Intention Form: eliminating a confusion of papers & emails

February 28th, 2009

Background

Each November the Residence Directors/Managers send out forms to each student in their building to determine the students’ housing plans for the Spring Semester.  These forms include a variety of options for students to choose:

  • No Change
  • Graduating: will not need room next semester
  • Student Teaching: will not need room next semester
  • Internship: no housing needed
  • Studying Abroad: no housing needed
  • Change room or hall for spring semester

In addition to these options, students can indicate whether they plan to live in the hall during Winterim or not. The students’ responses help the Residence Directors to plan for filling open spots in their hall during the winter break.

Problem

The Residence Directors found themselves sorting through hundreds of pieces of paper and emails trying to determine which students responded and which ones had not. To compound the problem, many of the responses required Residence Directors to follow up. Directors contacted students either by email or in person. Most of the time, keeping track of emails, papers, and other communication turned into a mess.

Problem Solved!

I created an online form where each student can log in using their student credentials and select their housing intentions for the spring semester. Residence Directors can then log into an administrative area where they can view all the responses for the students living in their building, email the student for follow-up contact, and add specific notes. Additionally, directors can see which students in their building have not responded. All of this information can be downloaded into Excel as well. No more sorting through hundreds of pieces of paper, or wondering who has responded and who hasn’t. Problem solved!

Timeclock: simplifying timesheets

February 28th, 2009

Background

One of the cool things about the timeclock is the ability to generate pdf timesheets on demand. The Hartman Union Building (HUB) administrative assistant is tasked with producing timesheets for approximately 100 student employees every two weeks.

Problem

The old time clock system generated arbitrary numbers for each student employee. At the end of each two week pay period the administrative assistant had to manually enter each employee’s time clock number, generate and print a timesheet report. As you can imagine, this was a tedious and time consuming task.

Problem Solved!

Before I began creating the timeclock I talked to the administrative assistant to identify what she liked and disliked about the current system. The problem outlined above was her greatest dislike. I created the new timeclock system to revolve around the unique student ID number issued to students upon their acceptance to the university. This allows the administrative assitant to select an employee by their name and generate a timesheet for that individual. Even better, I went one step further to reduce her workload: now she can generate a single pdf file with all employees’ timesheets ready to print. This takes only a few minutes instead of the entire afternoon!

Read more about how I generate the timesheets!

© Copyright 2009 – 2010 Randy Dustin

Hosted by A Small Orange