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

本文详细介绍使用 PHP 动态构建 PDF 文件的整个过程。使用免费 PDF 库 (FPDF) 或 PDFLib-Lite 等开源工具进行实验,并使用 PHP 代码控制 PDF 内容格式。

有时您需要准确控制要打印的页面的呈现方式。在这种情况下,HTML 就不再是最佳选择了。PDF 文件使您能够完全控制页面的呈现方式,以及文本、图形和图像在页面上的呈现方式。遗憾的是,用来构建 PDF 文件的 API 不属于 PHP 工具包的标准部件。现在您需要提供一点帮助。

当您在网络上搜索,寻找对 PHP 的 PDF 支持时,您首先发现的可能是商业 PDFLib 库及其开源版本 PDFLib-Lite。 这些都是很好的库,但是商业版本相当昂贵。PDFLib 库的精简版本库仅作为原始版本分发,当您尝试在托管环境下安装精简版本时,就会出现这个限制问题。

另一种选择是免费 PDF 库 (FPDF),它是本机 PHP,无需要进行任何编译,是完全免费的,因此,您不会像在未许可版本的 PDFLib 中那样看到水印。这个免费的 PDF 库正是我在本文中会用到的库。

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

清单 1. XML 数据

<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 代码。

<?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 页面


<?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

<?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

<?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. 添加结果表标题

<?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. 添加完整的结果表

<?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. 添加徽标图像

<?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票或票据,或填写表单,以及需要严格控制内容布局的任何项目。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索php
动态生成PDF文件
rdlc报表动态生成实例、ps入门实例详细教程、asp.net实例详细教程、动态网页制作实例教程、cad动态块实例教程,以便于您获取更多的相关知识。

时间: 2025-01-19 17:29:09

PHP在网页中动态生成PDF文件详细教程_php实例的相关文章

Java 动态生成 PDF 文件

每片文章前来首小诗:   今日夕阳伴薄雾,印着雪墙笑开颜.我心仿佛出窗前,浮在半腰望西天.  --泥沙砖瓦浆木匠 需求: 项目里面有需要java动态生成 PDF 文件,提供下载.今天我找了下有关了,系统得学习了解下. 开源的 iText 库使得 PDF 的创建变得轻松易行.下面介绍下   方案: -----------------------  iText V5.X.X 版 ----------------------- 第一步学习: 了解下: com.itextpdf.text.Documen

从Java应用程序动态生成PDF文件

pdf|程序|动态 如果应用程序需要动态生成 PDF 文档,则需要 iText 库.开放源码的 iText 库使 PDF 文档的创建能够在瞬间完成.本文介绍了 iText 并提供了使用它从 Java ? 技术应用程序生成 PDF 文档的由浅入深的指南.我们创建了一个示例应用程序以更好地理解 iText. 很多应用程序要求动态生成 PDF 文档.这类应用程序包括银行生成用于电子邮件投递的客户报表,到读者购买特定图书章节并以 PDF 格式接收这些文档.例子罗列下去是很多的.在本文中,将使用 iTex

如何从Java应用程序动态生成PDF文件

许多应用程序都要求动态生成 PDF 文档.这些应用程序涵盖从生成客户对帐单并通过电子邮件交付的银行到购买特定的 图书章节并以 PDF 格式接收这些图书章节的读者.这个列表不胜枚举.在本文中,我们将使用 iText Java 库生成 PDF 文 档.我们将向您演示一个样例应用程序,以便您可自行完成它并能更好地理解它. 熟悉 iText V5.3.0 版 iText 是一个可从 http://itextpdf.com/ 免费获取的 Java 库.iText 库非常强大,且支持生成 HTML.RTF

在Web应用中动态创建PDF文件

在一个最近的后勤项目中,客户要求我们建一个能让用户能从一个遗留系统查询出货信息的Web站点,有三个主要的需求: 1.出货信息必须以PDF文档的格式返回: 2.PDF文件必须能通过浏览器下载: 3.PDF文件必须能用Adobe Acrobat Reader阅读: 尽管我们的团队有很多J2EE Web应用的开发经验,但在PDF文档处理上却没有多少经验.我们需要找一个能在服务器端Web应用里产生复杂的PDF文档的纯Java类库.最后,我们发现iText(http://www.lowagie.com/i

PHP实现HTML生成PDF文件的方法_php技巧

本文实例讲述了在linux中利用HTML2FPDF与wkhtmltoimage把网页html直接生成pdf格式的文件方法,分享给大家供大家参考.具体实现方法如下: 找到一款在FPDF和HTML2FPDF源码基础上开发的一套开源程序,作者很给力.基本解决了中文(以及日语.韩语及东南亚和全球语言)乱码的问题,在Windows/Linux开发环境下测试可用,不需要安装别的组件支持,是没有VPS和独立服务器的网站开发者的福音. 不多说,源码名称是MPDF,官方地址是:http://www.mpdf1.c

PHP中使用imagick生成PSD文件缩略图教程_php技巧

第一步.安装ImageMagick 首先需要安装 ImageMagick http://imagemagick.org/script/binary-releases.php,因为 imagick 是一个可以供 PHP 调用 ImageMagick 功能的PHP扩展.(目前最新版本是:ImageMagick-6.8.9-5-Q16-x64-dll.exe) 安装目录不能有空格,我个人是安装在 C 盘根目录: 复制代码 代码如下: C:\ImageMagick 一路默认安装即可,安装完毕后打开 CM

PHP实现在线阅读PDF文件的方法_php实例

本文实例讲述了PHP实现在线阅读PDF文件的方法.分享给大家供大家参考.具体实现方法如下: <?php if(!function_exists('read_pdf')) { function read_pdf($file) { if(strtolower(substr(strrchr($file,'.'),1)) != 'pdf') { echo '文件格式不对.'; return; } if(!file_exists($file)) { echo '文件不存在'; return; } head

利用PHP生成CSV文件简单示例_php实例

前言 csv 文件其实和excel文件一样,都是表格类型.但PHP生成csv要比生成excel文件要简单的多,生成csv文件其实就是把以 , 号为分割符的字符串存成 .csv为扩展名的文件. 因为逻辑不难,具体请看下面的代码和注释. <?php /** * Created by PhpStorm. * User: chenyanphp@qq.com * Date: 2016/12/21 0021 * Time: 下午 12:08 */ // 头部标题 $csv_header = ['名称','性

PHP中使用smarty生成静态文件的例子_php实例

首先先要把需要静态化的内容填充到模版中去 复制代码 代码如下: #eg.这个是静态化首页的 function staticIndex(){ $newslist = $article->getArticles(null,54,'DESC',1,6,false,1,2,'',0,0,1);   if($newslist){    foreach($newslist as $k=>$v){     $newslist[$k]['title_all'] = $v['title'];     $news