Tabular data output is one of those tasks which is an integral part of almost every single Web project. Yet it's surprising how many different project-specific approaches you'll encounter, all of which bear some resemblance yet are never done in quite the same rigorous fashion. Because the task is so commonplace, personally I prefer to treat it like stamping out a widget, and rely on a drop in solution. While several such standardized solutions are available, I generally prefer to use HTML_Table, a great PEAR package which makes tabular data presentation a breeze. In this tutorial I'll walk you through several of HTML_Table's key features, additionally showing you how to integrate CSS and jQuery to create an eye-appealing and interactive tabular layout in no-time flat.

Installing HTML_Table

HTML_Table is a PEAR package, meaning you can use the command-line installer to install and maintain the package:
$ pear install HTML_Table
downloading HTML_Table-1.8.3.tgz ...
Starting to download HTML_Table-1.8.3.tgz (16,994 bytes)
......done: 16,994 bytes
install ok: channel://pear.php.net/HTML_Table-1.8.3

Creating a Table

HTML_Table is an object-oriented solution, allowing you to create tables in a very well-organized fashion. Given any data array (such as an array of objects or multidimensional array), you'll iterate over the array contents, moving not only from one row to the next but from one column to the next, outputting each table cell along the way. The following example iterates over a multidimensional array consisting of video game-related data. Because most of this is standard PHP code, I've highlighted the lines specific to HTML_Table:
<?php

  require_once "HTML/Table.php";


  $games = array(
   array("Call of Duty: Modern Warfare 2", "Activision Inc.", "$59.99"),
   array("Super Mario Galaxy 2", "Nintendo", "$49.99"),
   array("Grand Theft Auto IV", "Rockstar Games", "$19.99"),
   array("NBA 2K11", "2K Sports", "$39.99")
  );

  $table = new HTML_Table();

  for ($rows = 0; $rows < count($games); $rows++)
  {
    for($cols = 0; $cols < count($games[0]); $cols++)
    {
      $table->setCellContents($rows, $cols, $games[$rows][$cols]);
    }

  }

  echo $table->toHtml();

?>
Executing this example creates the table presented in Figure 1.

Figure 1.
Creating a Table Using HTML_Table

Adding Table Headers

While the table presented in Figure 1 is certainly readable, it's not exactly inspiring. For starters, it's missing headers which describe the type of information presented in each column. Use the setHeaderContents() method to add these headers:
...
$table = new HTML_Table();

$table->setHeaderContents(0, 0, 'Title');
$table->setHeaderContents(0, 1, 'Publisher');
$table->setHeaderContents(0, 2, 'Price');
...
Adding the headers to the previous example produces the table presented in Figure 2.

Figure 2.
Adding Headers to the Table

Alternating Row Coloring

The table presented in Figure 2 is certainly an improvement, but the presentation could be improved even further. For starters, the rows run together a little too closely. Let's make each row stand out on its own by alternating the row coloring using the altRowAttributes() method:
...
$table->altRowAttributes(1, null, array('bgcolor' => '#CCCCCC'));

echo $table->toHtml();
Revising the original example using the above code produces the table found in Figure 3.

Figure 3.
Alternating Row Coloring

Using CSS

There remain several more steps we can take to make the table even more eye-appealing, not to mention more maintainable. For starters, embedding style-specific code into the table isn't particularly practical, particularly because it could be moved into a CSS stylesheet. In fact, by taking advantage of CSS this table can be dramatically improved, resulting in the variation presented in Figure 4.

Figure 4.
CSS Really Can Create Beautiful Tables
Creating the table presented in Figure 4 is accomplished in two easy steps. Start by passing a DIV ID into the HTML_Table constructor:
$table = new HTML_Table(array("id" => "games"));
Next, add the following CSS to your page. It will modify the table in a variety of ways, changing how the overall table, headers, and rows are presented:
#games {
  width: 600px;
  border-collapse: collapse;
  font-family: Helvetica, Arial, sans-serif;
  font-size: 16px;
  font-style: normal;
  border: 1px solid black;
}

#games th {
  padding: 5px;
  font-size: 1.2em;
  text-align: left;
  border-bottom: 1px solid black;
  background-color: #F2C545;
}

#games td {
  padding: 5px;
}

Adding Interactive Row Highlighting

Alright, this is really starting to shape up nicely! I'd like to add one last feature, a bit of interactivity which will bring specific attention to each row as the user mouses over. Believe it or not this is most easily accomplished using CSS' hover selector. Add the following to your CSS definitions:
#games tr:hover {
  background-color: #A4E666;
}
The hover selector works in conjunction with all modern browsers. You'll also want to comment out or remove the altRowAttributes() method call. With the CSS in place, any row mouseovers will cause the row to turn green, as demonstrated in Figure 5.

Figure 5.
Adding a Bit of Interactivity

Sorting Rows Interactively

While you can make an educated guess regarding how the user would like to sort the table, it's always ideal to give the user the power to override this default. Add interactive sorting using the Tablesorter jQuery plugin. Once configured, the user can click on any table header to resort the contents. Of course, to integrate this feature you'll need to reference both jQuery and the Tablesorter plugin in your document. Additionally, you'll need to reformat the table a bit to use both the THEAD and TBODY tags. I've provided all of the code used to integrate this interactive feature in the following listing, highlighting key lines:
<html>
 <head>

<script type="text/javascript" 
        src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
  google.load("jquery", "1.5");
</script>

<script type="text/javascript" src="jquery.tablesorter.min.js"></script>
 
<script type="text/javascript">
  google.setOnLoadCallback(function() {
    $("#games").tablesorter(); 
  });
</script>

</head>
<body>

<?php

require_once "HTML/Table.php";

$games = array(
 array("Call of Duty: Modern Warfare 2", "Activision Inc.", "$59.99"),
 array("Super Mario Galaxy 2", "Nintendo", "$49.99"),
 array("Grand Theft Auto IV", "Rockstar Games", "$19.99"),
 array("NBA 2K11", "2K Sports", "$39.99")
);

$table = new HTML_Table(array("id" => "games", 
          "class" => "tablesorter"), 0, TRUE);

$head =& $table->getHeader();
$head->setHeaderContents(0, 0, 'Title');
$head->setHeaderContents(0, 1, 'Publisher');
$head->setHeaderContents(0, 2, 'Price');

$body =& $table->getBody();
for ($rows = 0; $rows < count($games); $rows++)
{
  for($cols = 0; $cols < count($games[0]); $cols++)
  {
    $body->setCellContents($rows, $cols, $games[$rows][$cols]);
  }

}

echo $table->toHtml();

?>
</body>
</html>

Conclusion

Using powerful tools such as HTML_Table, CSS and jQuery, it really is incredible what's possible with just a few lines of code. What tools do you use to format your tables? Tell us about them in the comments!

About the Author

Jason Gilmore is founder of the publishing, training, and consulting firm WJGilmore.com. He is the author of several popular books "Easy PHP Websites with the Zend Framework", "Easy PayPal with PHP", and "Beginning PHP and MySQL, Fourth Edition". Follow him on Twitter at @wjgilmore.