PHP制作pdf文档方法

  本篇博客是在看完 php+mysql web书以后自己的测试代码,虽然是测试代码,但不是简单的粘贴复制,为了学习thinkPHP框架,自己就用这个来做的,而且这本书已经有年头了。原书的代码中的方法,在查阅手册的时候,很多都已经弃用了,所以分享给大家还是有必要的。php制作pdf文档的方法有很多,我写的只是其中一种,大家有时间可以多看看。好了,进入正题

  准备工作:

    1、php手册(在线php关于pdf地址: http://php.net/manual/zh/intro.pdf.php )

    2、PDFlib(http://www.pdflib.com/download/pdflib-family/pdflib-9/ 下载)

  开始安装PDFlib扩展

    第一步,下载最新的pdflib扩展,

    我下载下来后里面有很多东西

    

    

    

    

    我的php版本是PHP Version 5.2.17所以我选的是php_520里面的文件,将里面的文件名称改成libpdf_php.dll =》php_pdf.dll

    第二步安装

      将php_pdf.dll文件放到php的ext目录

         打开php.ini文件将里面extension=php_pdf.dll去掉分号(如果没有,就添加上这一行),如果没有找到添加即可。

      第三步重启apache或IIS

    

  建立项目pdfApp

    这里我为了学习thinkPHP,所以使用的是thinkPHP框架,我们的目标是根据用户的答题情况->作出成绩判断->生成用户的pdf成绩证书

    由于项目比较小,我们简单使用一个控制器就可以完成,代码就不分开贴了,最下面有完整的IndexController代码

    首先,进入index方法显示信息搜集页面(就是controller中的index方法)

    

    

    进入根据选择跳转到score方法

    

 

    生成PDF证书

    下面的一页就是代码中测试制作第二页的输出

    怎么会有这么大的水印啊,影响美观。请不要相信那个大大的水印是我加的

    由于PDFlib并不是开源免费的,所以、、、、、

    

 

    

  完整代码:

    需要注意的是:

    PDFlib的使用也是有两种:面向对象和面向过程

    区别是:对于手册中的所有方法都是面向过程的方法,在使用面向对象时,只需要把前面的前缀'PDF_'用对象调用替换即可,

    同时忽略方法中的'resource $pdfdoc' 参数

    

  1 <?php
  2 namespace Home\Controller;
  3 use Think\Controller;
  4 class IndexController extends Controller {
  5     public function index(){
  6         $this->display();
  7     }
  8     public function score() {
  9         $name = I('post.name');
 10         $question_1 = I('post.q1');
 11         $question_2 = I('post.q2');
 12         $question_3 = I('post.q3');
 13         
 14         if ( ('' == $question_1) || ('' == $question_2) || ('' == $question_3) || ('' == $name)) {
 15             # code...
 16             $err_url = U('Index/index');
 17             $this->assign('url',$err_url);
 18             $this->display('nullError');
 19         }else {
 20             $score = 0;
 21             1 == $question_1 && $score++;
 22             1 == $question_2 && $score++;
 23             1 == $question_3 && $score++;
 24 
 25             //convert score to a percentage
 26             $score = $score / 3 * 100;
 27 
 28             if($score < 50) {
 29               // this person failed
 30                 $this->display('notPass');
 31               
 32             }  else {
 33               // create a string containing the score to one decimal place
 34               $score = number_format($score, 1);
 35               $this->assign('name',$name);
 36               $this->assign('score',$score);
 37               $this->display('isPass');
 38             }
 39         }
 40     }
 41     public function pdflib() {
 42         $name = I('post.name');
 43         $score = I('post.score');
 44         if(!$name || !$score) {
 45             echo 'name and score is null';
 46         }else {
 47             // 开始制作pdf文档
 48             // 注意:PDFlib的使用也是有两种:面向对象和面向过程
 49             // 区别是:对于手册中的所有方法都是面向过程的方法,在使用面向对象时,只需要把前面的前缀'PDF_'用对象调用替换即可,
 50             // 同时忽略方法中的'resource $pdfdoc' 参数
 51             // 例如我们可以创建一个pdf对象  $pdf = new \PDFlib();
 52             // 也可以使用 $pdf = pdf_new();创建一个pdf资源句柄
 53             try {
 54                 $date = date('F d, Y');  // 获取系统当前时间
 55                 //  实例化一个PDFlib对象,注意我们的PDFlib由于是在php的扩展库中,所以这里记得前面加上'\',thinkPHP此时就回去全区命名空间下
 56                 //  查找这个类问价
 57                 $pdf = new \PDFlib();
 58                 // PDF_begin_document() 这个方法在内存中创建一个pdf文档
 59                 if(false == $pdf->begin_document('','')) {
 60                     die('Error: '.$pdf->get_errmsg());
 61                 }
 62 
 63                 $width = 792;
 64                 $height = 612;
 65                 // 向文档中添加新的页面
 66                 $pdf->begin_page_ext($width,$height,'');
 67             
 68                 // 开始定义并画出边框(pdf中的长度和位置的单位均是:像素)
 69                 $inset = 20; // 边框和页面边缘的距离
 70                 $border = 10; // 边框宽度
 71                 $inner = 2; // 边框和两条边线的距离
 72                 // PDF_rect 方法是画出一个矩形,注意坐标原点是 左下角
 73                 $pdf->rect($inset-$inner,$inset-$inner,$width-2*($inset-$inner),$height-2*($inset-$inner));
 74                 $pdf->stroke(); // PDF_stroke 描绘用当前颜色和路径宽度描绘出路径
 75                 
 76                 $pdf->setlinewidth($border);   // PDF_setlinewidth 设置线条宽度
 77                 $pdf->rect($inset+$border/2,
 78                    $inset+$border/2,
 79                    $width-2*($inset+$border/2),
 80                    $height-2*($inset+$border/2));
 81                 $pdf->stroke();
 82 
 83                 $pdf->setlinewidth(1.0);
 84                 $pdf->rect($inset+$border+$inner,
 85                         $inset+$border+$inner,
 86                         $width-2*($inset+$border+$inner),
 87                         $height-2*($inset+$border+$inner)
 88                         );
 89                 $pdf->stroke();
 90                 // 添加标题
 91                 $fontname = 'Times-Roman';
 92                 // PDF_load_font 方法是:搜索和准备字体
 93                 $font = $pdf->load_font($fontname,'winansi','');
 94                 $pdf->setcolor('fill', 'rgb', 1, 0, 0, 0); // PDF_setcolor  设置 填充颜色和描绘路径颜色
 95                 $pdf->setfont($font,20);
 96                 $pdf->show_xy($date,50,490);  // PDF_show_xy 在给的的位置输出文本内容
 97                 $pdf->setcolor('fill', 'rgb', 0, 0, 0, 0); // red
 98                 $pdf->setfont($font,48);
 99                 $start_x = ($width-$pdf->stringwidth('PHP Certification',$font,'12'))/2;
100                 $pdf->show_xy('PHP Certification',$start_x,490);
101                 
102                 // 添加内容
103                 $font = $pdf->load_font($fontname,'iso8859-1','');
104                 $pdf->setfont($font,26);
105                 $start_x = 70;
106                 $pdf->show_xy('This is to certify that:',$start_x,430);
107                 $pdf->show_xy(strtoupper($name),$start_x+90,391);
108 
109                 $font = $pdf->load_font($fontname,'iso8859-1','');
110                 $pdf->setfont($font,20);
111                 $pdf->show_xy('has demonstrated that they are certifiable by passing a rigorous exam', $start_x, 340);
112                 $pdf->show_xy('consisting of three multiple choice questions.',$start_x, 310);
113                     
114                 $pdf->show_xy("$name obtained a score of $score".'%.', $start_x, 260);
115                     
116                 $pdf->show_xy('The test was set and overseen by the ', $start_x, 210);
117                 $pdf->show_xy('Fictional Institute of PHP Certification', $start_x, 180);
118                 $pdf->show_xy("on $date.", $start_x, 150);
119                 $pdf->show_xy('Authorised by:', $start_x, 100);
120 
121                 // 添加签名
122                 // PDF_load_image  打开图像文件
123                 $signature = $pdf->load_image('png',WEB_ROOT."/Public/images/signature.png",'');
124                 $pdf->fit_image($signature,200, 75, '');  // PDF_fit_image 将图片放到指定位置
125                 $pdf->close_image($signature);  // 关闭文件
126                 
127                 // 开始画出星型图章 
128                 $pdf->setcolor('fill', 'rgb', 0, 0, .4, 0);  // 设置PDF_fill方法用的颜色
129                 $pdf->setcolor('stroke', 'rgb', 0, 0, 0, 0); // 设置PDF_stroke方法用的颜色
130                 // 画出左侧飘带
131                 $pdf->moveto(630, 150);  // PDF_moveto 将画图点移动到指定位置
132                 $pdf->lineto(610, 55);   // PDF_lineto 从当前点画出一条线到指定位置
133                 $pdf->lineto(632, 69);
134                 $pdf->lineto(646, 49);
135                 $pdf->lineto(666, 150);
136                 $pdf->closepath();   // PDF_closepath 关闭当前路径
137                 $pdf->fill();  // PDF_fill 用指定颜色填充到路径内 
138 
139                 // outline ribbon 1
140                 $pdf->moveto(630, 150);
141                 $pdf->lineto(610, 55);
142                 $pdf->lineto(632, 69);
143                 $pdf->lineto(646, 49);
144                 $pdf->lineto(666, 150);
145                 $pdf->closepath();
146                 $pdf->stroke();
147 
148                 // draw ribbon 2
149                 $pdf->moveto(660, 150);
150                 $pdf->lineto(680, 49);
151                 $pdf->lineto(695, 69);
152                 $pdf->lineto(716, 55);
153                 $pdf->lineto(696, 150);
154                 $pdf->closepath();
155                 $pdf->fill();
156 
157                 // -> outline ribbon 2
158                 $pdf->moveto(660, 150);
159                 $pdf->lineto(680, 49);
160                 $pdf->lineto(695, 69);
161                 $pdf->lineto(716, 55);
162                 $pdf->lineto(696, 150);
163                 $pdf->closepath();
164                 $pdf->stroke();
165 
166 
167                 $pdf->setcolor('fill', 'rgb', 1, 0, 0, 0); // red
168 
169                 //调用自定义方法,画出图章礼花
170                 $this->draw_star(665, 175, 32, 57, 10, $pdf, true);
171 
172                 //outline rosette
173                 $this->draw_star(665, 175, 32, 57, 10, $pdf, false);
174 
175                 // PDF_end_page 结束当前页
176                 
177                 // 这里如果需要继续制作第二页,第三页。。。。
178                 $pdf->end_page_ext("");
179 
180                     $pdf->set_info("Creator", "hello.php");
181                 $pdf->set_info("Author", "Rainer Schaaf");
182                 $pdf->set_info("Title", "Hello world (PHP)!");
183 
184                 $pdf->begin_page_ext(595, 842, "");
185 
186                 $font = $pdf->load_font("Helvetica-Bold", "winansi", "");
187 
188                 $pdf->setfont($font, 24.0);
189                 $pdf->set_text_pos(50, 700);
190                 $pdf->show("Hello world!");
191                 $pdf->continue_text("(says PHP)");
192                 $pdf->end_page_ext("");
193                 // 第二页结束,看明白了吗?
194 
195                 // PDF_end_document 结束文档 
196                 $pdf->end_document("");
197                 // PDF_get_buffer 得到PDF输出缓存
198                 $data = $pdf->get_buffer();
199 
200                 // 设置浏览器头信息
201                 header('Content-type: application/pdf');
202                 header('Content-disposition: inline; filename=test.pdf');
203                 header('Content-length: ' . strlen($data));
204 
205                 // 输出PDF
206                 echo $data;
207             }
208             catch (PDFlibException $e) {
209                 die("PDFlib exception occurred in hello sample:\n" .
210                         "[" . $e->get_errnum() . "] " . $e->get_apiname() . ": " .
211                         $e->get_errmsg() . "\n");
212             }
213             catch (Exception $e) {
214                     die($e);
215             }
216 
217         }
218     }
219     // 画礼花图章方法
220     // 具体算法自行理解,所用方法上面都有所说明,
221     function draw_star($centerx, $centery, $points, $radius, $point_size, $pdf, $filled)  {
222         $inner_radius = $radius-$point_size;
223 
224         for ($i = 0; $i<=$points*2; $i++)  {
225                 $angle= ($i*2*pi())/($points*2);
226 
227                 if($i%2) {
228                         $x = $radius*cos($angle) + $centerx;
229                         $y = $radius*sin($angle) + $centery;
230                 } else {
231                         $x = $inner_radius*cos($angle) + $centerx;
232                         $y = $inner_radius*sin($angle) + $centery;
233                 }
234 
235                 if($i==0) {
236                         $pdf->moveto($x, $y);
237                 } else if ($i==$points*2) {
238                         $pdf->closepath();
239                 } else {
240                         $pdf->lineto($x, $y);
241                 }
242         }
243         if($filled) {
244                 $pdf->fill_stroke();
245         } else {
246                 $pdf->stroke();
247         }
248     }
249 
250     public function pdf() {
251         try {
252                 $p = new \PDFlib();
253 
254                 /*  open new PDF file; insert a file name to create the PDF on disk */
255                 if ($p->begin_document("", "") == 0) {
256                         die("Error: " . $p->get_errmsg());
257                 }
258 
259                 $p->set_info("Creator", "hello.php");
260                 $p->set_info("Author", "Rainer Schaaf");
261                 $p->set_info("Title", "Hello world (PHP)!");
262 
263                 $p->begin_page_ext(595, 842, "");
264 
265                 $font = $p->load_font("Helvetica-Bold", "winansi", "");
266 
267                 $p->setfont($font, 24.0);
268                 $p->set_text_pos(50, 700);
269                 $p->show("Hello world!");
270                 $p->continue_text("(says PHP)");
271                 $p->end_page_ext("");
272 
273                 $p->end_document("");
274 
275                 $buf = $p->get_buffer();
276                 $len = strlen($buf);
277 
278                 header("Content-type: application/pdf");
279                 header("Content-Length: $len");
280                 header("Content-Disposition: inline; filename=hello.pdf");
281                 print $buf;
282                 $p->open_file('1.pdf');
283         }
284         catch (PDFlibException $e) {
285                 die("PDFlib exception occurred in hello sample:\n" .
286                         "[" . $e->get_errnum() . "] " . $e->get_apiname() . ": " .
287                         $e->get_errmsg() . "\n");
288         }
289         catch (Exception $e) {
290                 die($e);
291         }
292         $p = 0;
293     }
294 }

    

    代码中用到的方法:

    PDF_begin_document() 这个方法在内存中创建一个pdf文档

    PDF_begin_page_ext()  向文档中添加新的页面

    PDF_rect          方法是画出一个矩形,注意坐标原点是 左下角

    PDF_stroke                  描绘用当前颜色和路径宽度描绘出路径

    PDF_setlinewidth         设置线条宽度

    PDF_load_font             搜索和准备字体.

    PDF_setcolor               设置 填充颜色和描绘路径颜色

    PDF_show_xy              在给的的位置输出文本内容

      PDF_load_image          打开图像文件

    PDF_fit_image            将图片放到指定位置

    PDF_close_image         关闭文件

      PDF_moveto              将画图点移动到指定位置

    PDF_lineto                 从当前点画出一条线到指定位置

    PDF_closepath           关闭当前路径

    PDF_fill                     用指定颜色填充到路径内

    PDF_end_document   结束文档

    PDF_get_buffer         得到PDF输出缓存

  好了,方法有很多,常用的也就是这么多,如果有兴趣,愿意的话可以去看看php手册:http://php.net/manual/zh/ref.pdf.php

 

  以上就是今天一天的学习成果,哎时间真快,都天黑了,完了,吃饭走。

  欢迎大家转载,收藏,吐槽,哈哈、、、、

      

    

    

posted @ 2015-03-07 22:03  虢国技酱  阅读(2828)  评论(0编辑  收藏  举报