本篇博客是在看完 php+mysql web書以后自己的測試代碼,雖然是測試代碼,但不是簡單的粘貼復制,為了學習thinkhtml' target='_blank'>PHP框架,自己就用這個來做的,而且這本書已經有年頭了。原書的代碼中的方法,在查閱手冊的時候,很多都已經棄用了,所以分享給大家還是有必要的。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 HomeController; 3 use ThinkController; 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 1140 $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 2149 $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 2158 $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); // red168 169 //調用自定義方法,畫出圖章禮花170 $this->draw_star(665, 175, 32, 57, 10, $pdf, true);171 172 //outline rosette173 $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 // 輸出PDF206 echo $data;207 }208 catch (PDFlibException $e) {209 die('PDFlib exception occurred in hello sample:' .210 '[' . $e->get_errnum() . '] ' . $e->get_apiname() . ': ' .211 $e->get_errmsg() . '');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:' .286 '[' . $e->get_errnum() . '] ' . $e->get_apiname() . ': ' .287 $e->get_errmsg() . '');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
以上就是今天一天的學習成果,哎時間真快,都天黑了,完了,吃飯走。
歡迎大家轉載,收藏,吐槽,哈哈、、、、
PHP編程鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答