PHP在网页中动态生成PDF文件详细教程

我们将使用女子旱滑比赛的得分来演示动态构建 PDF 文件的过程。这些得分是从 Web 中获得并被转换成 XML。清单 1 显示了一个示例 XML 数据文件。

清单 1. XML 数据

?
1
2
3
4
5
6
7
8
9
10
11
12
13
< events >
  < event name = "Beast of the East 2011" >
   < game score1 = "88" team1 = "Toronto Gore-Gore Rollergirls" team2 = "Montreal La Racaille" score2 = "11" >
   < game score1 = "58" team1 = "Toronto Death Track Dolls" team2 = "Montreal Les Contrabanditas" score2 = "49" >
    ...
  </ game ></ game ></ event >
  < event name = "Dustbowl Invitational 2011" >
    ...
  </ event >
  < event name = "The Great Yorkshire Showdown 2011" >
    ...
  </ event >
</ events >

XML 的根元素是一个 events 标记。按事件对数据进行分组,每个事件都包含多个比赛。在 events 标记内,是一系列的 event 标记,在这些标记中有多个 game 标记。 这些 game 标记中包含参加比赛的两个队的名称以及他们在比赛中的得分。

清单 2 展示了用来读取 XML 的 PHP 代码。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
function getResults() {
  $xml = new DOMDocument();
  $xml ->load( 'events.xml' );
  $events = array ();
  foreach ( $xml ->getElementsByTagName( 'event' ) as $event ) {
   $games = array ();
   foreach ( $event ->getElementsByTagName( 'game' ) as $game ) {
    $games []= array ( 'team1' => $game ->getAttribute( 'team1' ),
     'score1' => $game ->getAttribute( 'score1' ),
     'team2' => $game ->getAttribute( 'team2' ),
     'score2' => $game ->getAttribute( 'score2' ) );
   }
   $events []= array ( 'name' => $event ->getAttribute( 'name' ),
    'games' => $games );
  }
  return $events ;
}
?>

这段脚本实现了一个 getResults 函数,以便将 XML 文件读入 DOM 文档。然后使用 DOM 调用遍历所有 event 和 game 标记,以构建一个事件阵列。该数列内的每个元素都是一个散列表,包含事件名称和比赛项目的阵列。结构基本上是 XML 结构的内存版。

为了测试这个脚本的作用,将构建一个 HTML 导出页面,使用 getResults 函数读取文件,然后以一系列 HTML 表的形式输出数据。清单 3 显示了该测试所用的 PHP 代码。

清单 3. 结果 HTML 页面

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<? php
include_once('getresults.php');
$ results = getResults ();
foreach( $results as $event ) {
?>
< h1 ><? php echo( $event['name'] ) ?></ h1 >
 
<? php
foreach( $event['games'] as $game ) {
  $s1 = (int)$game['score1'];
  $s2 = (int)$game['score2'];
?>
 
<? php
}
?>
< table >< tbody >< tr >
  < td style="font-weight:<?php echo( ( $s1 > $s2 ) ? 'bold' : 'normal') ?>">
   <? php echo( $game['team1'] ) ?></ td >
  < td ><? php echo( $s1 ) ?></ td >
  < td style="font-weight:<?php echo( ( $s2 > $s1 ) ? 'bold' : 'normal') ?>">
   <? php echo( $game['team2'] ) ?></ td >
  < td ><? php echo( $s2 ) ?></ td >
</ tr ></ tbody ></ table >
<? php
}
?>

通过代码 getresults.php,XML 数据文件被上传到 Web 服务器,您可以查看 HTML 结果,这与 图 1 类似。
图 1. HTML 格式的竞赛结果



在该结果中,对获胜队使用了粗体,以便查看哪支队赢得了哪场比赛。

构建 PDF

获得数据之后,应将重点放在构建 PDF 文件上。第一步是下载 FPDF 库,然后将其安装在与现有应用文件集相同的目录中。实际上,只要是在 PHP 库路径中,您可以将它安装在任何您喜欢的地方。追踪您放置字体目录的地方,因为您需要设置 ‘FPDF_FONTPATH',如 清单 4 所示。

清单 4. PDF Hello World

?
1
2
3
4
5
6
7
8
9
10
11
<?php
define( 'FPDF_FONTPATH' , '/Library/WebServer/Documents/derby/font/' );
 
require ( 'fpdf.php' );
 
$pdf = new FPDF();
$pdf ->SetFont( 'Arial' , '' ,72);
$pdf ->AddPage();
$pdf ->Cell(40,10, "Hello World!" ,15);
$pdf ->Output();
?>

这段脚本实际上是一个 “Hello World”,但采用的是 PDF 格式而不是 HTML。这段脚本执行的第一个操作是使用 define 语句设置 FPDF 字体目录的位置。然后使用 require 语句引入 FPDF 库。这段脚本从该库创建了一个 FPDF 对象,设置字体,添加一个页面,然后使用 Cell 方法将一些文本放在该页面上,并输出 PDF。

图 2 展示了一切都正常情况下的结果。

图 2. PDF 格式的 Hello World



如果没有看到 PDF,那么您可能想在命令行运行这段脚本,查看是否丢失了 fpdf.php 文件或者存在其他问题。

既然 PDF 呈现正常,那么现在应该将其与旱滑结果文件合并,并查看可以动态生成哪些内容。清单 5 展示了该合并操作的第一个版本。

清单 5. 显示结果的首版 PDF

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
define( 'FPDF_FONTPATH' , '/Library/WebServer/Documents/derby/font/' );
 
require ( 'fpdf.php' );
require ( 'getresults.php' );
 
class PDF extends FPDF
{
function EventTable( $event )
{
   $this ->Cell(40,10, $event [ 'name' ],15);
   $this ->Ln();
}
}
 
$pdf = new PDF();
$pdf ->SetFont( 'Arial' , '' ,48);
foreach ( getResults() as $event ) {
  $pdf ->AddPage();
  $pdf ->EventTable( $event );
}
$pdf ->Output();
?>

我们没有从外部扩展 FPDF 类别,而是使用我们自己的 PDF 子类来扩展 FPDF 类别。在这些子类内,我们创建了一个名为 EventTable 的新方法,为给定事件构建了一个结果表。在这种情况下,我们从小处着手,只输出了事件名称。该名称位于脚本底部,包装在 foreach 循环中,该脚本为每个事件添加一个页面,然后调用 EventTable 方法。

可在 图 3 中看到这段脚本的输出。

图 3. 动态 PDF 的第一个版本




向下滚动页面,以展示每个事件都在自己的页面上。此处的下一步操作是开始将结果添加到页面。

构建结果表

在构建 PDF 文件时,构建无表结构就像构建 HTML 一样简单。构建表的方法是构建许多宽度、字体、填充颜色、行颜色等各不相同的单元。

清单 6 展示了设置表的标题栏的添加代码。

清单 6. 添加结果表标题

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
define( 'FPDF_FONTPATH' , '/Library/WebServer/Documents/derby/font/' );
 
require ( 'fpdf.php' );
require ( 'getresults.php' );
 
class PDF extends FPDF
{
function EventTable( $event )
{
   $this ->SetFont( '' , 'B' , '24' );
   $this ->Cell(40,10, $event [ 'name' ],15);
   $this ->Ln();
 
   $this ->SetXY( 10, 45 );
 
   $this ->SetFont( '' , 'B' , '10' );
   $this ->SetFillColor(128,128,128);
   $this ->SetTextColor(255);
   $this ->SetDrawColor(92,92,92);
   $this ->SetLineWidth(.3);
 
   $this ->Cell(70,7, "Team 1" ,1,0, 'C' ,true);
   $this ->Cell(20,7, "Score 1" ,1,0, 'C' ,true);
   $this ->Cell(70,7, "Team 2" ,1,0, 'C' ,true);
   $this ->Cell(20,7, "Score 2" ,1,0, 'C' ,true);
   $this ->Ln();
}
}
 
$pdf = new PDF();
$pdf ->SetFont( 'Arial' , '' ,10);
foreach ( getResults() as $event ) {
  $pdf ->AddPage();
  $pdf ->EventTable( $event );
}
$pdf ->Output();
?>

此处的添加代码用于设置字体、颜色和行宽。然后它将呈现包含四个标题列的几个单元格。然后调用 Ln 方法(该方法与回车键等效)启用一个新行。

在浏览器中查看这段脚本时,可以看到类似 图 4 的内容。

图 4. 包含表的标题行的页面



在 图 4 中,标题以白色文本呈现在灰色背景上。这种格式有助于将其与呈现在标题下面的数据进行区分。要呈现比赛结果,请在 清单 7 中添加以下代码。

清单 7. 添加完整的结果表

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
define( 'FPDF_FONTPATH' , '/Library/WebServer/Documents/derby/font/' );
 
require ( 'fpdf.php' );
require ( 'getresults.php' );
 
class PDF extends FPDF
{
function EventTable( $event )
{
   $this ->SetFont( '' , 'B' , '24' );
   $this ->Cell(40,10, $event [ 'name' ],15);
   $this ->Ln();
 
   $this ->SetFont( '' , 'B' , '10' );
   $this ->SetFillColor(128,128,128);
   $this ->SetTextColor(255);
   $this ->SetDrawColor(92,92,92);
   $this ->SetLineWidth(.3);
 
   $this ->Cell(70,7, "Team 1" ,1,0, 'C' ,true);
   $this ->Cell(20,7, "Score 1" ,1,0, 'C' ,true);
   $this ->Cell(70,7, "Team 2" ,1,0, 'C' ,true);
   $this ->Cell(20,7, "Score 2" ,1,0, 'C' ,true);
   $this ->Ln();
 
   $this ->SetFillColor(224,235,255);
   $this ->SetTextColor(0);
   $this ->SetFont( '' );
 
   $fill = false;
 
   foreach ( $event [ 'games' ] as $game )
   {
     $this ->SetFont( 'Times' ,((int) $game [ 'score1' ]>(int) $game [ 'score2' ])? 'BI' : '' );
     $this ->Cell(70,6, $game [ 'team1' ], 'LR' ,0, 'L' , $fill );
     $this ->Cell(20,6, $game [ 'score1' ], 'LR' ,0, 'R' , $fill );
     $this ->SetFont( 'Times' ,((int) $game [ 'score1' ]<(int) $game [ 'score2' ])? 'BI' : '' );
     $this ->Cell(70,6, $game [ 'team2' ], 'LR' ,0, 'L' , $fill );
     $this ->Cell(20,6, $game [ 'score2' ], 'LR' ,0, 'R' , $fill );
     $this ->Ln();
     $fill =! $fill ;
   }
   $this ->Cell(180,0, '' , 'T' );
}
}
 
$pdf = new PDF();
$pdf ->SetFont( 'Arial' , '' ,10);
foreach ( getResults() as $event ) {
  $pdf ->AddPage();
  $pdf ->EventTable( $event );
}
$pdf ->Output();
?>

除了标题行之外,在 EventTable 方法中还有一个 foreach 循环,它将在每个比赛上进行迭代。图 5 显示了用于此用途的代码。

图 5. 包含结果表的 PDF

$fill 变量可通过切换来改变表中每行的颜色。优胜队的名称和得分用加粗、斜体字体表示,这样可以清晰显示它们。还需注意的是,字体从标题的 Arial 字体更改成了显示比赛内容所用的 Times 字体。

要完成示例代码,则需要添加一些图形。

使用图形进行修饰

向 PDF 添加图像非常容易。首先需要从 Web 抓取一个图像。我抓取了一个旱滑参赛队的徽标,并将其存储为 PNG 格式的图像。 此后,我一直使用 清单 8 中的新代码。

清单 8. 添加徽标图像

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
define( 'FPDF_FONTPATH' , '/Library/WebServer/Documents/derby/font/' );
 
require ( 'fpdf.php' );
require ( 'getresults.php' );
 
class PDF extends FPDF
{
function EventTable( $event )
{
   $this ->Image( 'logo.png' ,5,5,33);
 
   $this ->SetXY( 40, 15 );
 
   $this ->SetFont( '' , 'B' , '24' );
   $this ->Cell(40,10, $event [ 'name' ],15);
   $this ->Ln();
 
   $this ->SetXY( 10, 45 );
 
   $this ->SetFont( '' , 'B' , '10' );
   $this ->SetFillColor(128,128,128);
   $this ->SetTextColor(255);
   $this ->SetDrawColor(92,92,92);
   $this ->SetLineWidth(.3);
 
   $this ->Cell(70,7, "Team 1" ,1,0, 'C' ,true);
   $this ->Cell(20,7, "Score 1" ,1,0, 'C' ,true);
   $this ->Cell(70,7, "Team 2" ,1,0, 'C' ,true);
   $this ->Cell(20,7, "Score 2" ,1,0, 'C' ,true);
   $this ->Ln();
 
   $this ->SetFillColor(224,235,255);
   $this ->SetTextColor(0);
   $this ->SetFont( '' );
 
   $fill = false;
 
   foreach ( $event [ 'games' ] as $game )
   {
    $this ->SetFont( 'Times' ,((int) $game [ 'score1' ]>(int) $game [ 'score2' ])? 'BI' : '' );
    $this ->Cell(70,6, $game [ 'team1' ], 'LR' ,0, 'L' , $fill );
    $this ->Cell(20,6, $game [ 'score1' ], 'LR' ,0, 'R' , $fill );
    $this ->SetFont( 'Times' ,((int) $game [ 'score1' ]<(int) $game [ 'score2' ])? 'BI' : '' );
    $this ->Cell(70,6, $game [ 'team2' ], 'LR' ,0, 'L' , $fill );
    $this ->Cell(20,6, $game [ 'score2' ], 'LR' ,0, 'R' , $fill );
    $this ->Ln();
    $fill =! $fill ;
   }
   $this ->Cell(180,0, '' , 'T' );
}
}
 
$pdf = new PDF();
$pdf ->SetFont( 'Arial' , '' ,10);
foreach ( getResults() as $event ) {
  $pdf ->AddPage();
  $pdf ->EventTable( $event );
}
$pdf ->Output();
?>

清单 8中的关键方法是 Image 方法,它为图像、位置和宽度选取一个文件名称。所有其它参数都是可选的,因此您只指定您想要的信息便可。

到 SetXY 的一些新调用会将文本和表左右移动到适当的位置,防止其覆盖图像。

图 6 显示了这段脚本的输出结果。

图 6. 带有徽标图像的已完成的 PDF

该 PDF 库还提供了其他方法来呈现图形、添加流文本、添加超链接、管理页边距和方向等结构,您可以完全控制您的 PDF 文件。

结束语


使用合适的工具,通过 PHP 构建 PDF 文件是非常容易的。这种方法非常适用于打印发x票或票据,或填写表单,以及需要严格控制内容布局的任何项目。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值