摘要
本论文简要介绍了 PHPXMLPDF 等技术的原理以及它们的应用情况力图运用 PHP 面向对象的特性, 构建出一套基于 PHP 和 XML 的在线 PDF 文档生成系统文中详细探讨了整个系统的组成部分以及各自的实现过程并在最后给出一个运用这套系统实现的动态创建报表的实例
- Abstract
- This article introduced the fundamentls of PHP,XML and PDF and their application situation at present,expecting to build a PHP&XML-based dynamic PDF documents creating system through the PHP's OO features. Furthermore,we discussed in detail on the components of the whole system and their respective realizing methods. Finally,we represented an example of creating reports dynamically using this system.
关键词
- PHP
- XML XSLT
- DTD
1. 引言
在信息技术飞速发展的时代, 无论政府企业还是个人, 他们对如何通过信息技术提高自身工作效率, 节省开支具有浓厚的兴趣他们急切要找到一种优秀的技术, 可以把传统上以纸张为媒介的文件报表票单据手册申请书等等等等转化为一种可以非常方便的在互联网以及内部网络自动生成传播下载浏览打印的电子文档而如今最为热门的无纸化办公电子商务等等都将以此为基础
这种文档格式就 Adobe 公司的 PDF(可移植文档格式), 它已是全世界电子版文档分发的公开实用标准 任何浏览器只要安装 Acrobat reader 5.0 的插件, 便可以自由浏览下载打印 PDF 文档 PDF 无疑具有其它电子文档格式不可比拟的优越性
我们知道 B/S 系统作为当前以及将来最流行的一种软件架构, 可以很好的实现各种基于浏览器的 web 应用程序, 而 PHP 作为一种优秀的 Web 编程语言, 特别适合开发用于处理用户表单输入, 查询数据库等针对浏览器用户的前端应用程序由于 PHP 是开放源码的, 这使得它的使用比其它同类的 Web 脚本语言更为广泛, 它的功能也在不断的扩充和完善之中现在最新的 PHP 版本已经可以很好的支持 PDF,XML 等通过系统提供的 API, 我们能非常快捷的生成 PDF 文档, 而最具魅力的是, 我们可以通过 PHP, 查询数据库或 XML 数据文件并将结果插入所生成的 PDF 文档之中, 形成各种具有绝佳的浏览和打印效果的报表单据手册等
不难看出, 结合 PHPXMLPDF 三项技术, 构造出一种可以在线动态生成 PDF 文档的系统是极具现实意义的, 其主要表现在:
. 文档可以在网络上生成, 并通过网络分发节省大量的人力物力具有精确美观的打印效果, 真正实现了无纸化办公
. 电子商务交易过程中的各种票据凭证都可以通过 PHP 脚本程序在线生成, 并转为 PDF 格式发送给客户
. 企业 MIS 系统中各种面向打印的报表的生成, 并可直接通过浏览器获得, 无须安装任客户端, 使用极为方便
. 以前文件流转是 "先打印, 后分发", 每年花在印刷上的费用是政府企业沉重的负担而 PDF 文档 "先散发, 后打印", 接件人可以在浏览后, 再按需要打印印刷的费用大大减少而且, 很有利于环保事业
2. 课题简介
在某些软件项目的开发过程中, 我们遇到一个很关键的问题就是大量面向打印的报表单据的生成我们知道, html 适合浏览, 但不适合格式规范的打印因此必需找到一种可以由 PHP 动态生成, 且具有良好的打印效果的文档格式而这正是我研究这个课题的最直接的需求 明白了这一点, 我们就很自然的想到了 PDF 以及 PHP 的 PDF 支持库 PDFLib 通过 PDFLib 提供的一套 API, 我们可以很容易在 PHP 脚本动态创建 PDF 文档但是这只是一套非常基本的函数, 只能进行一些简单的输出, 如线条文本矩形框等, 而且每输出一个对象之前, 都要为其指定坐标如果直接使用来这套函数来做一些实际的应用, 比如复杂的报表的生成, 其困难程度是难以想象的我们不可能为创建这样一个报表, 而事先算好各个元素的坐标, 并把单元格用矩形框一个一个的画出来
所以, 我们第一步要做的就是利用 PHP 面向对象的编程方法将这套基本的 API 进行封装, 以产生多个实用的具有独立功能的对象模块 (如 page 对象 table 对象 text 对象等) 应该说, 这一块是此项目最基本, 也是最重要的部分我参考并部分采用
了国外一些类似的开放源码的程序, 在此基础上开发出了一套功能较为强大的类库大大简化了 PDF 文档的生成, 特别是其中的 table 对象, 可以象 HTML 中的 TABLE 标记一样任意嵌套, 轻松快捷的实现各种复杂的表格的绘制(这对动态生成报表是非常有用的)
生成 PDF 的问题解决以后, 我们面临了新的问题, 举个例子来说, 数据库查询页面如何将包含大量信息的结果集以及其它信息传给 PDF 生成页面? 最初我们想到的方法是通过文本文件传递, 即在数据库查询页面将数据写到一个文本文件当中, 并对其
中不同类别的数据定义一套区分的标记, PDF 生成页面读取此文件, 将内容插入到 PDF 中 但是这样做, 并不可靠因为在这个文本文件中, 我们采用特定的字符 (或空格) 来分离数据, 如果恰好有用数据中也包含同样的字符或空格呢? 可见, 以这种方式传递数据是有隐患的其实上面我们提到在文本文件中用不同的标记区分不同类别的数据而这正是 XML 技术的思想何不一步到为采用 XML 来作为数据传递的手段呢? 况且 PHP 对 XML 和 XSLT 具有很好的支持, 通过 expat 解析器, 我们可以任意提取 XML 文档中的数据, 也可以通过 PHP 的 XSLT 引擎 Sablotron 对 XML 文档进行任意转换
首先由 XML 生成器将数据 (来自数据库或用户输入等) 放到一个符合事先定义好的 DTD 的 XML 文档中, 此文档对其中的数据内容进行描述, 不包含任何格式信息 然后由 XML 转换器将这个 XML 文档转换成包含显示样式信息的另一个 XML 文档 最后由 PDF 生成器读取这个文档, 根据其中的内容和显示样式生成相应的 PDF 文档在这一个过程中, 我要做的是再次运用 PHP 的面向对象特性, 构建出可重用的类: XMLWriter(生成 XML 文件)XMLParser(解析 XML 文件)以及 XMLTransformer(对 XSLT 函数的封装)
系统构建成功后, 就是具体的应用了主要是进销存系统中各种报表单据的动态生成
3. 可行性分析
开发一个功能强大适应性好的 PDF 文档在线生成系统, 必然需要弹性大灵活性
高的开发模型我们提出的基于 PHP 和 XML 的 PDF 文档在线生成技术, 为各种面向打印的应用, 如报表单票据手册等提供了新的思路我们用 PHP 来查询数据库, 处理用户输入, 并在此基础上生成原始的 XML 文档; 然后通过 XSLT 将该 XML 文档加上显示层信息, 生成另外一个新的 XML 文档最后利用 PDF 生成器将这个新的 XML 文档转化为相应格式的 PDF 文档对于最初生成的 XML 文档, 我可以做二度利用, 因为该文档包含了所有的有用信息, 可以非常容易的被其它应用程序处理如果我们想改变信息在 PDF 文档显示的样式, 可以非常容易的实现只要专门人员修改相应的 XSL 样式单文件即可, 不需要对其它环节做任何修改, 具有非常好的灵活性除此之外, PHPXMLPDF 三者都具有极好的可移植性, 可以跨平台使用 对该系统的研究并非凭空想象的, 它建立在直接的需求之上的到目前为止, 这套技术已经投入实际应用, 收到了极为满意的效果实践证明, 运用 PHP 和 XML 开发出的一套在线 PDF 文档生成系统具有广阔和非常实际的应用前景
4 总体设计
本课题主要完成四个基础模块的设计及编程实现这四个类模块分别为 PDFCreatorXMLWriterXMLTransfomer 以及 XMLParser 它们分布于系统的各个环节之中, 具有各自独立的功能和作用, 是系统的核心组成部分(见下图)
系统构成图
从图中可见, 四者在本系统中又是紧密联系的有机整体 XMLWriter 作为系统的输
入接口, 负责生成原始的 XML 数据文件该文件的格式规范 (DTD) 由我们事先编写好, 而 XMLWriter 按照该 DTD 生成相应的 XML 文档这个 XML 文档接着交由 XMLTransfomer 处理, XMLTransfomer 其实是对 PHP 提供的 XSLT 函数的封装, 它一般接受两个参数, 其中之一是需要转换的 XML 文档, 另一个是相应的 XSL 样式单文件 XMLTransfomer 正是根据该样式单文件将原始的 XML 文档转化为符合这个样式单样式的另一个 XML 文档 (包含信息在 PDF 文档中放置的格式) 然后, 这个新的 XML 文件继续交由 PDF 生成器进行处理而这个过程有分为两个部分: 首先, 必需对这个 XML 文档进行解析, 提取其中所需的数据, 这一步有 XMLParser 来完成, XMLParser 对此 XML 文档进行解析, 将其转化为一棵对象树, XML 文档中每一个节点都是一个对象, 每个对象都有各自的属性 (即相应节点的所有信息) 这样一来, 我们可以非常方便的访问这个 XML 文档的任意内容之后, 要做的就是将该 XML 文档中读出的信息 (包括格式信息和内容信息) 用 PDFCreator 转化为最终的 PDF 文档的输出
5.应用示例
在这里, 我们运用上面的这套系统创建一个面向打印的报表库存历史事
表这个报表包含的信息有: 报表名称 (协和库存历史事务表) 单位建表日期等, 另外就是从数据库中提取的数据了, 品名 (LLPROD) 批号 (LLOC) 等级 (LCLS) 仓库 (LWHS) 库位 (LLOCT) 数量 (LNUM) 日期 (LDATE) 等假设我们已经用 XMLWriter 生成了下面的原始 XML 文档(report.xml):
平方米
- 20020611
- W2308
- 1234
- a
- 01
- 0001
- 200
- 20020609
- W2307
- 4321
- a
- 01
- 0001
- 100
- 20020609
该文档包含了这张报表的所有有用信息, 我们需要用特定的 XSL 样式单为其加上格式信息 XMLTransformer 执行转换的代码如下:
- $xslt = new XMLTransformer ("report.xsl", "report.xml");
- $xslt->apply("pdfreport.xml");
- ?>
转换后生成的新的 XML 文档如下:
库存历史事务表
单位: 平方米
品名 | 批号 | 等级 | 仓库 | 库位 | 数量 | 日期 |
---|---|---|---|---|---|---|
W2308 | 1234 | a | 01 | 0001 | 200 | 20020609 |
W2307 | 4321 | a | 01 | 0001 | 100 | 20020609 |
建表日期: 20020611
用 XMLParser 对该 XML 文档解析后, 得到一个包含所有信息的对象树, 我们可以非常方便的访问其中的内容生成的 PDF 报表如下图:
程序片断如下:
- include("../include/pc_init.inc"); ? >include("xmlparser.inc");
- $xmlobject = getRootNode("report.xml");
- // get the attrs of root element
- $pageSet = $xmlobject - >attrs;
- // get the report-head
- $head = $xmlobject - >nodes[0];
- // code ignored...
- ? >
- function draw_line( & $parent, $line) {
- $line = &pc_create_object($parent, "line");
- $line - >pc_set_linestyle($line - >attrs["LINETYPE"]);
- $line - >pc_set_width($line - >attrs["SIZE"]);
- $line - >pc_set_alignment("center");
- if ($line - >attrs["SHOW"] == false) {
- $line - >pc_set_linecolor("white");
- }
- $line - >pc_set_margin(array("top" = >$line - >attrs["TOP"], "bottom" = >$line - >attrs["BOTTOM"], "left" = >0, "right" = >0));
- }
- function draw_text( & $parent, $text) {
- // code ignored...
- }
- function draw_table( & $parent, $table) {
- // code ignored...
- }
- function addhead( & $parent, $head) {
- for ($i = 0; $i < $head - >n; $i++) {
- switch ($head - >nodes[$i] - >name) {
- case "LINE":
- draw_line($parent, $head - >nodes[$i]);
- break;
- case "TEXT":
- draw_text($parent, $head - >nodes[$i]);
- break;
- }
- }
- }
- //..
- ? >
- // Create a PDF Document
- $PDF = &pc_create_pdf(array("Author" = >"cyman", "Title" = >"a report example"));
- // Create an A4-format page
- $Page1 = &pc_create_page($PDF, $pageSet["PAGETYPE"]);
- addhead($Page1, $head);
- $PDF - >pc_draw(); ? >
6. 总结
在几个月来的毕业设计过程中, 虽然忙碌, 却非常充实通过对一个实际的课题的分析, 研究, 论证, 实现感觉收获颇多目前, 这套系统已投入使用, 收到了非常满意的效果, 可以很容易的做出美观实用的报表单据等但是, 由于时间上的仓促以及自己水平的有限, 这套系统仍有许多不足之处其中最遗憾就是, 没有能定义出一套对各种文档 (包括报表单据手册等等) 都通用的 XML 标记, 并编制通用的程序将这个 XML 文档转化为 PDF, 就如同浏览器解析 HTML 一样这样就不必为每一种文档都定义各自的 XML 标记并编写相对应的转换程序, 可以大大提高工作效率
虽然毕业设计已经结束, 但
来源: https://www.php1.cn/detail/php-77a4da8989.html