以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 WORD to XML, HTML to XML 』 (http://bbs.xml.org.cn/list.asp?boardid=13) ---- Xml to Pdf 专题 (http://bbs.xml.org.cn/dispbbs.asp?boardid=13&rootid=&id=15127) |
-- 作者:Coral -- 发布时间:3/5/2005 2:32:00 PM -- Xml to Pdf 专题 基于PHP与XML的PDF文档生成技术 转自:动态网制作指南 www.knowsky.com 摘要 本论文简要介绍了PHP、XML、PDF等技术的原理以及它们的应用情况。力图运用PHP面向对象的特性,构建出一套基于PHP和XML的在线PDF文档生成系统。文中详细探讨了整个系统的组成部分以及各自的实现过程。并在最后给出一个运用这套系统实现的动态创建报表的实例。 Abstract PHP XML XSLT DTD PDF 2. 课题简介 在某些软件项目的开发过程中,我们遇到一个很关键的问题就是大量面向打印的报表、单据的生成。我们知道,HTML适合浏览,但不适合格式规范的打印。因此必需找到一种可以由PHP动态生成,且具有良好的打印效果的文档格式。而这正是我研究这个课题的最直接的需求。 明白了这一点,我们就很自然的想到了PDF以及PHP的PDF支持库PDFLib。通过PDFLib提供的一套API,我们可以很容易在PHP脚本动态创建PDF文档。但是这只是一套非常基本的函数,只能进行一些简单的输出,如线条、文本、矩形框等,而且每输出一个对象之前,都要为其指定坐标。如果直接使用来这套函数来做一些实际的应用,比如复杂的报表的生成,其困难程度是难以想象的。我们不可能为创建这样一个报表,而事先算好各个元素的坐标,并把单元格用矩形框一个一个的画出来。 3. 可行性分析 开发一个功能强大、适应性好的PDF文档在线生成系统,必然需要弹性大、灵活性 本课题主要完成四个基础模块的设计及编程实现。这四个类模块分别为PDFCreator、XMLWriter、XMLTransfomer以及XMLParser。它们分布于系统的各个环节之中,具有各自独立的功能和作用,是系统的核心组成部分(见下图)。 系统构成图 入接口,负责生成原始的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): <?xml version="1.0" encoding="gb2312"?> <report> <report_param> <title>库存历史事务表</title> <unit>平方米</unit> <date>20020611</date> </report_param> <report_records> <record> <llprod>W2308</llprod> <lloc>1234</lloc> <lcls>a</lcls> <lwhs>01</lwhs> <lloct>0001</lloct> <lnum>200</lnum> <ldate>20020609</ldate> </record> <record> <llprod>W2307</llprod> <lloc>4321</lloc> <lcls>a</lcls> <lwhs>01</lwhs> <lloct>0001</lloct> <lnum>100</lnum> <ldate>20020609</ldate> </record> </report_records> </report>
该文档包含了这张报表的所有有用信息,我们需要用特定的XSL样式单为其加上格式信息。XMLTransformer执行转换的代码如下: <?php $xslt = new XMLTransformer ("report.xsl", "report.xml"); $xslt->apply("pdfreport.xml"); ?>
转换后生成的新的XML文档如下:
<?xml version="1.0" encoding="gb2312"?> <pdfreport pagetype="a4" pagesize="25" top="20" bottom="20" left="20" right="20"> <head> <line top="5" bottom="5" size="50%" linetype="single" show="false"/> <text fontsize="30" fontlaguage="cn" align="center">库存历史事务表</text> <line top="5" bottom="30" size="80%" linetype="double" show="true"/> <text fontsize="12" fontlaguage="cn" align="left">单位:平方米</text> </head>
<body> <table> <tr><th>品名</th><th>批号</th><th>等级</th><th>仓库</th><th>库位</th><th>数量</th><th>日期</th></tr> <tr><td>W2308</td><td>1234</td><td>a</td><td>01</td><td>0001</td><td>200</td><td>20020609</td></tr> <tr><td>W2307</td><td>4321</td><td>a</td><td>01</td><td>0001</td><td>100</td><td>20020609</td></tr> </table> </body> <foot> <line top="5" bottom="5" size="50%" linetype="single" show="false"/> <text fontsize="12" fontlaguage="cn" align="center">建表日期:20020611</text> </foot> </pdfreport> 用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标记并编写相对应的转换程序,可以大大提高工作效率。 |
-- 作者:bigc -- 发布时间:5/26/2005 12:45:00 PM -- pdf 不是那么简单的吧 |
-- 作者:zsldownloa -- 发布时间:7/13/2005 6:01:00 PM -- 挺新鲜的啊 |
-- 作者:netyang -- 发布时间:5/8/2006 12:37:00 AM -- 在网上见了很多次了,是个好方向,值得继续做下去~~ |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
62.500ms |