专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »PHP教程 » word文档生成pdf:基于PHP和XML的PDF文档生成技术 »正文

word文档生成pdf:基于PHP和XML的PDF文档生成技术

来源: 发布时间:星期一, 2009年1月12日 浏览:14次 评论:0
  1.    引言

  在信息技术飞速发展时代无论政府、企业还是个人他们对如何通过信息技术提高自身工作效率节省开支具有浓厚兴趣他们急切要找到种优秀技术可以把传统上以纸张为媒介文件、报表、票单据、手册、申请书等等等等转化为种可以非常方便在互联网以及内部网络自动生成、传播、下载、浏览、打印电子文档而如今最为热门“无纸化办公”、“电子商务”等等都将以此为基础

  这种文档格式就Adobe公司PDF(可移植文档格式)它已是全世界电子版文档分发公开实用标准   任何浏览器只要安装Acrobat reader 5.0 插件便可以自由浏览、下载、打印PDF文档PDF无疑具有其它电子文档格式不可比拟优越性

  我们知道B/S系统作为当前以及将来最流行种软件Software架构可以很好实现各种基于浏览器Web应用而PHP作为种优秀Web编程语言特别适合开发用于处理用户表单输入查询数据库等针对浏览器用户前端应用由于PHP是开放源码这使得它使用比其它同类Web脚本语言更为广泛功能也在不断扩充和完善的中现在最新PHP版本已经可以很好支持PDFXML等通过系统提供API我们能非常快捷生成PDF文档而最具魅力我们可以通过PHP查询数据库或XML数据文件并将结果插入所生成PDF文档的中形成各种具有绝佳浏览和打印效果报表、单据、手册等

  不难看出结合PHP、XML、PDF 3项技术构造出种可以在线动态生成PDF文档系统是极具现实意义其主要表现在:

  ·文档可以在网络上生成并通过网络分发节省大量人力物力具有精确美观打印效果真正实现了无纸化办公

  ·电子商务交易过程中各种票据、 凭证都可以通过PHP脚本在线生成并转为PDF格式发送给客户

  ·企业MIS系统中各种面向打印报表生成并可直接通过浏览器获得无须安装任客户端使用极为方便

  ·以前文件流转是"先打印,后分发",每年花在印刷上费用是政府、企业沉重负担而PDF文档"先散发,后打印",接件人可以在浏览后,再按需要打印印刷费用大大减少而且,很有利于环保事业

  2.    课题介绍

  在某些软件Software项目开发过程中我们遇到个很关键问题就是大量面向打印报表、单据生成我们知道HTML适合浏览但不适合格式规范标准打印因此必需找到种可以由PHP动态生成且具有良好打印效果文档格式而这正是我研究这个课题最直接需求 明白了这我们就很自然想到了PDF以及PHPPDF支持库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文档中数据也可以通过PHPXSLT引擎Sablotron对XML文档进行任意转换

  首先由“XML生成器”将数据(来自数据库或用户输入等)放到个符合事先定义好DTDXML文档中此文档对其中数据内容进行描述不包含任何格式信息 然后由“XML转换器”将这个XML文档转换成包含显示样式信息个XML文档 最后由“PDF生成器”读取这个文档根据其中内容和显示样式生成相应PDF文档在这个过程中我要做是再次运用 PHP面向对象特性构建出可重用类:XMLWriter(生成XML文件)、XMLParser(解析XML文件)以及XMLTransformer(对XSLT封装)

  系统构建成功后就是具体应用了主要是进销存系统中各种报表、单据动态生成

  3.    可行性分析

  开发个功能强大、适应性好PDF文档在线生成系统必然需要弹性大、灵活性

  高开发模型我们提出基于PHP和XMLPDF文档在线生成技术为各种面向打印应用如报表、单票据、手册等提供了新思路我们用PHP来查询数据库处理用户输入并在此基础上生成原始XML文档;然后通过XSLT将该XML文档加上显示层信息生成另外个新XML文档最后利用“PDF生成器”将这个新XML文档转化为相应格式PDF文档对于最初生成XML文档我可以做 2度利用该文档包含了所有有用信息可以非常容易被其它应用处理如果我们想改变信息在PDF文档显示样式可以非常容易实现只要专门人员修改相应XSL样式单文件即可不需要对其它环节做任何修改具有非常好灵活性除此的外PHP、XML、PDF 3者都具有极好可移植性可以跨平台使用 对该系统研究并非凭空想象它建立在直接需求的上到目前为止这套技术已经投入实际应用收到了极为满意效果实战证明运用PHP和XML开发出套在线PDF文档生成系统具有广阔和非常实际应用前景

  4 总体设计

  本课题主要完成 4个基础模块设计及编程实现这 4个类模块分别为PDFCreator、XMLWriter、XMLTransfomer以及XMLParser它们分布于系统各个环节的中具有各自独立功能和作用是系统核心组成部分(见下图)

  系统构成图

  从图中可见 4者在本系统中又是紧密联系有机整体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):

     <?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 = 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报表如下图:

  片断如下:

<?  ( "..//pc_init.inc" );?>
<?  ( "xmlparser.inc" );
<?
$xmlobject=getRootNode("report.xml");
// get the attrs of root element
$pageSet=$xmlobject->attrs;
// getthe report-head
$head=$xmlobject->nodes[0];
// code ignored...
?>
<?
 function draw_line(&$parent,$line){
  $line = &pc_create_object( $parent, "line" );
  $line->pc__linestyle( $line->attrs["LINETYPE"]);
  $line->pc__width( $line->attrs["SIZE"] );
  $line->pc__alignment( "center" );
  ($line->attrs["SHOW"]false){
    $line->pc__linecolor( "white" );
  }
    $line->pc__margin( .gif' />( "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){
       "LINE":draw_line($parent,$head->nodes[$i]);;
       "TEXT":draw_text($parent,$head->nodes[$i]);;
      }
    }
  }
//..
?>
<?
// Create a PDF Document
 $PDF = &pc_create_pdf( .gif' />( "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标记并编写相对应转换可以大大提高工作效率

  虽然毕业设计已经结束但是我将会今后日子里继续这个课题研究



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: