前言
上星期給畢設(shè)網(wǎng)站添加了markdown編輯器春缕,然后周末突然想到如果給編輯器添加一個(gè)導(dǎo)出pdf的功能應(yīng)該挺不錯(cuò)的(話說(shuō)簡(jiǎn)書為啥不能導(dǎo)出pdf呢),所以就從網(wǎng)上找了一個(gè)生成pdf的PHP插件艘蹋,叫做 tcpdf锄贼,東西很大,連帶著實(shí)例文件接近16m女阀,花了一天時(shí)間去弄這個(gè)宅荤。
其實(shí)這個(gè)根據(jù)這個(gè)插件的實(shí)例很快就能弄出pdf來(lái),不過(guò)剩下的時(shí)間我都在研究怎么能讓生成的pdf更好看强品,很明顯我失敗了膘侮。普通文本還好,如果有這樣的代碼
的榛,要么是顯示不出來(lái)了琼了,而顯示出來(lái)的部分也是亂七八糟的。如下:
雖然對(duì)我來(lái)說(shuō)沒(méi)什么價(jià)值夫晌,但畢竟研究了一番雕薪,寫個(gè)小日志記錄一下吧。
文件引入
從 TCPDF下載最新的版本晓淀,雖然下載包中附帶了65個(gè)demo所袁,但它沒(méi)告訴我哪些文檔是必須引入的。那我們直接來(lái)看程序文件凶掰。打開主程序文件tcpdf.php
燥爷,從開始的代碼可以看出,以下文件必須被包含:
tcpdf_autoconfig.php
include文件夾
在搜索所有文件中的require_once
懦窘,有如下文件:
tcpdf_barcodes_1d.php
tcpdf_barcodes_2d.php
ok前翎,將tcpdf.php
和上述文件復(fù)制到項(xiàng)目文件夾,
require_once('./tcpdf.php');
$pdf = new TCPDF();
執(zhí)行畅涂,然后就出錯(cuò)了:
Warning: opendir(C:\Practice\Apache24\htdocs\demo\PDF/fonts/,C:\Practice\Apache24\htdocs\demo\PDF/fonts/): in C:\Practice\Apache24\htdocs\demo\PDF\tcpdf.php on line 4148
Warning: opendir(C:\Practice\Apache24\htdocs\demo\PDF/fonts/): failed to open dir: No such file or directory in C:\Practice\Apache24\htdocs\demo\PDF\tcpdf.php on line 4148
TCPDF ERROR: Could not include font definition file: helvetica
顯然還要將下載包中的fonts文件夾復(fù)制到項(xiàng)目中港华。
執(zhí)行
經(jīng)過(guò)上面的引入和調(diào)試,現(xiàn)在能正常實(shí)例化了午衰,在上面代碼中我實(shí)例化tcpdf
方法未傳遞任何參數(shù)立宜,但實(shí)際上該方法有7個(gè)參數(shù)可傳遞,如下:
屬性 | 說(shuō)明 | 默認(rèn)值 |
---|---|---|
$orientation | 設(shè)置pdf頁(yè)面的方向 | Portrait |
$unit | 設(shè)置pdf單元的測(cè)量單位 | mm |
$format | 頁(yè)面的版式 | A4 |
$unicode | 是否使用unicode | true |
$encoding | 字符編碼 | utf-8 |
$diskcache | 該功能被廢棄 | false |
$pdfa | 啟用/關(guān)閉pdf/a | true |
具體說(shuō)明如下:
$orientation
用來(lái)設(shè)置pdf頁(yè)面的方向臊岸,有兩個(gè)參數(shù):
參數(shù)名 | 含義 | 默認(rèn) |
---|---|---|
P/Portrait | 縱向 | true |
L/Landscape | 橫向 | false |
$unit
用來(lái)設(shè)置pdf單元的測(cè)量單位橙数,有四個(gè)參數(shù)
參數(shù)名 | 含義 | 默認(rèn) |
---|---|---|
pt: point | 點(diǎn)數(shù) | false |
mm: millimeter | 毫米 | true |
cm: centimeter | 厘米 | false |
in: inch | 英寸 | false |
$format
表示頁(yè)面的版式,如 A4等帅戒。而他默認(rèn)的也是 A4商模。 tcpdf支持很多版式,可以到tcpdf_static.php中的$page_formats
屬性中查看。
$unicode
布爾類型施流,true
代表是輸入文本是$unicode
响疚。這個(gè)沒(méi)什么說(shuō)的,一般都是unicode瞪醋,默認(rèn)為true就行忿晕。
$encoding
字符編碼,默認(rèn)是utf-8
银受。
$diskcache
這個(gè)參數(shù)官網(wǎng)沒(méi)多做解釋践盼,程序文件也是,不過(guò)在其中寫了DEPRECATED FEATURE
宾巍,顯然該功能被廢棄了咕幻,不建議使用,直接設(shè)置為false
即可顶霞。
$pdfa
PDF/A是PDF 的 ISO 標(biāo)準(zhǔn)肄程,它是為長(zhǎng)期保存文件而設(shè)計(jì)的,屏蔽了一些編輯功能选浑。即設(shè)置`$pdfa = true**的話蓝厌,生成的pdf是不能夠編輯的。
好了古徒,弄清楚了這7個(gè)參數(shù)拓提,可以實(shí)例化了,當(dāng)然如果你只是簡(jiǎn)單的使用一下可以直接進(jìn)行實(shí)例化隧膘,因?yàn)檫@7個(gè)參數(shù)都有默認(rèn)值代态,而一般這些默認(rèn)值不用修改。
配置
tcpdf的配置選項(xiàng)很多疹吃,大致分成4個(gè)部分膨处,包括文檔的信息設(shè)置王带,頁(yè)眉頁(yè)腳設(shè)置绊含,文本間距設(shè)置缤谎,正文設(shè)置蒋搜。其中分成若干小部分篡撵。在完成功能之前,簡(jiǎn)單介紹一下豆挽,這幾部分必要的方法育谬。
如下:
1 文檔的信息設(shè)置
包括 SetCreator(文檔創(chuàng)建者名稱)
,SetAuthor(設(shè)置作者)
帮哈,SetTitle(設(shè)置文檔標(biāo)題)
膛檀,SetKeywords(文檔關(guān)鍵詞)
。這幾個(gè)方法的參數(shù)沒(méi)什么可說(shuō)的,string類型咖刃,主要就是用來(lái)設(shè)置文檔的屬性的泳炉,如下面的東西一樣:
2 頁(yè)眉頁(yè)腳設(shè)置
包括SetHeaderData
,setFooterData
嚎杨,setHeaderFont
花鹅,setFooterFont
SetHeaderData
方法有6個(gè)參數(shù),包括:
屬性 | 說(shuō)明 | 默認(rèn)值 |
---|---|---|
$ln | logo文件路徑 | '' |
$lw | logo寬度 | 0 |
$ht | 頁(yè)眉標(biāo)題 | '' |
$hs | 頁(yè)眉的說(shuō)明文字 | '' |
$tc | 文本的rgb顏色 | array(0,0,0) (黑色) |
$lc | 頁(yè)眉下劃線的顏色 | array(0,0,0) (黑色) |
而setFooterData
只有兩個(gè)參數(shù)枫浙,頁(yè)腳文本顏色和下劃線的顏色刨肃。
而setHeaderFont
,setFooterFont
分別是設(shè)置頁(yè)眉和頁(yè)腳的字體箩帚,參數(shù)只有一個(gè)真友,且注意是數(shù)組類型,且傳遞的數(shù)組格式如下:
array(family, style, size)
對(duì)應(yīng)的是font-family
紧帕,font-style
盔然,font-size
。
另外焕参,如果不希望使用頁(yè)眉頁(yè)腳轻纪,可以使用setPrintHeader
和setPrintFooter
方法關(guān)閉頁(yè)眉頁(yè)腳,只要傳遞參數(shù)false
即可叠纷。
3 文本間距設(shè)置
間距包含正文間距和頁(yè)眉頁(yè)腳的間距刻帚,有三個(gè)方法SetMargins
,SetHeaderMargin
涩嚣,SetFooterMargin
崇众。
SetMargins
是用于正文的,有三個(gè)參數(shù)航厚,分別表示左側(cè)顷歌、上側(cè)、右側(cè)的間距幔睬。SetHeaderMargin
和SetFooterMargin
分別是頁(yè)眉與頁(yè)腳的間距眯漩。
4.設(shè)置正文
正文設(shè)置包括 分頁(yè),圖片比例麻顶,正文字體等赦抖。
首先利用 SetAutoPageBreak
開啟分頁(yè)。該方法傳遞兩個(gè)參數(shù)辅肾,參數(shù)1用戶啟動(dòng)或禁用自動(dòng)分頁(yè)队萤,而參數(shù)2只有參數(shù)1等于true時(shí)才起作用,它定義了頁(yè)面距底部的距離矫钓。
再利用AddPage
方法新添分頁(yè)要尔。同時(shí)舍杜,該方法如果前面已有頁(yè)面,該方法會(huì)在將頁(yè)腳添加到頁(yè)面中 并自動(dòng)添加下一頁(yè)赵辕,否則直接添加新一頁(yè)既绩。
字體的設(shè)置包括,setFontSubsetting
匆帚、SetFont
熬词、SetDefaultMonospacedFont
。
setFontSubsetting
這個(gè)方法我沒(méi)弄懂吸重,因?yàn)椴涣私馐裁唇凶煮w構(gòu)造子集互拾,跳過(guò)。SetFont
就是用來(lái)設(shè)置正文字體嚎幸,參數(shù)傳遞和setHeaderFont
類似颜矿,但該方法將三個(gè)選項(xiàng)分成了三個(gè)參數(shù)傳遞,而不是傳遞數(shù)組嫉晶。另外骑疆,如果是生成中文pdf需要尤其注意,必須設(shè)置字體為stsongstdlight
替废,否則會(huì)出現(xiàn)中文亂碼箍铭。
當(dāng)然還有正文寫入了,如果只是普通文檔椎镣,一般使用Write
方法诈火,共有12個(gè)參數(shù),所以我就不一一介紹了状答,說(shuō)一下必填的兩個(gè)參數(shù)冷守,也就是前兩個(gè)參數(shù),$h
表示行高惊科,$txt
表示要打印的內(nèi)容拍摇。其他可以默認(rèn)。
如果打印html文檔且包含了css文件馆截,就需要使用writeHTML
方法充活,該方法有6個(gè)參數(shù),但必填的只有一個(gè)就是需要打印的內(nèi)容蜡娶,其他的參數(shù)可以是默認(rèn)值混卵。
好了,配置翎蹈、參數(shù)介紹完畢,按照我介紹的步驟一步步的來(lái)男公,就能生成pdf了荤堪,下面是我自己寫的生成代碼:
class pdf {
# 常量設(shè)置
const PDF_LOGO = '\Logo\logo_big.png'; // LOGO路徑 該路徑是tcpdf下
const PDF_LOGO_WIDTH = '20'; // LOGO寬度
const PDF_TITLE = 'www.liuweime.me'; //
const PDF_HEAD = '上電腦課';
const PDF_FONT = 'stsongstdlight';
const PDF_FONT_STYLE = '';
const PDF_FONT_SIZE = 10;
const PDF_FONT_MONOSPACED = 'courier';
const PDF_IMAGE_SCALE='1.25';
# tcpdf對(duì)象存儲(chǔ)
protected $pdf = null;
/**
* 構(gòu)造函數(shù) 引入插件并實(shí)例化
*/
public function __construct() {
# 實(shí)例化該插件
$this->pdf = new TCPDF();
}
/**
* 設(shè)置文檔信息
* @param $user string 文檔作者
* @param $title string 文檔標(biāo)題
* @param $subject string 文檔主題
* @param $keywords string 文檔關(guān)鍵字
* @return null
*/
protected function setDocumentInfo($user = '', $title = '', $subject ='', $keywords = '') {
if(empty($user) || empty($title)) return false;
# 文檔創(chuàng)建者名稱
$this->pdf->SetCreator(APP_NAME);
# 作者
$this->pdf->SetAuthor($user);
# 文檔標(biāo)題
$this->pdf->SetTitle($title);
# 文檔主題
if(!empty($subject)) $this->pdf->SetSubject($subject);
# 文檔關(guān)鍵字
if(!empty($keywords)) $this->pdf->SetKeywords($keywords);
}
/**
* 設(shè)置文檔的頁(yè)眉頁(yè)腳信息
* @param null
* @return null
*/
protected function setHeaderFooter() {
# 設(shè)置頁(yè)眉信息
# 格式 logo地址 logo寬度 頁(yè)眉標(biāo)題 頁(yè)眉說(shuō)明文字 頁(yè)眉字體顏色 頁(yè)眉下劃線顏色
$this->pdf->SetHeaderData(self::PDF_LOGO , self::PDF_LOGO_WIDTH , self::PDF_TITLE , self::PDF_HEAD , array(35 , 35 , 35) , array(221,221,221));
# 設(shè)置頁(yè)腳信息
# 格式 頁(yè)腳字體顏色 頁(yè)腳下劃線顏色
$this->pdf->setFooterData(array(35 , 35 , 35) , array(221,221,221));
# 設(shè)置頁(yè)眉頁(yè)腳字體
$this->pdf->setHeaderFont(array('stsongstdlight' , self::PDF_FONT_STYLE , self::PDF_FONT_SIZE));
$this->pdf->setFooterFont(array('helvetica' , self::PDF_FONT_STYLE , self::PDF_FONT_SIZE));
}
/**
* 關(guān)閉頁(yè)眉頁(yè)腳
* @param null
* @return null
*/
protected function closeHeaderFooter() {
# 關(guān)閉頁(yè)頭
$this->pdf->setPrintHeader(false);
# 關(guān)閉頁(yè)腳
$this->pdf->setPrintFooter(false);
}
/**
* 設(shè)置間距 包括正文間距 頁(yè)眉頁(yè)腳間距
* @param null
* @return null
*/
protected function setMargin() {
# 設(shè)置默認(rèn)的等寬字體
$this->pdf->SetDefaultMonospacedFont('courier');
# 正文左側(cè) 上側(cè) 右側(cè)間距
$this->pdf->SetMargins(15, 7, 15);
# 頁(yè)眉間距
$this->pdf->SetHeaderMargin(5);
# 頁(yè)腳間距
$this->pdf->SetFooterMargin(10);
}
/**
* 正文設(shè)置 包括 分頁(yè) 圖片比例 正文字體
* @param null
* @return null
*/
protected function setMainBody() {
# 開啟分頁(yè) true開啟 false關(guān)閉 開啟分頁(yè)時(shí)參數(shù)2起作用 表示正文距底部的間距
$this->pdf->SetAutoPageBreak(true , 25);
# 設(shè)置圖片比例
$this->pdf->setImageScale(self::PDF_IMAGE_SCALE);
#
$this->pdf->setFontSubsetting(true);
# 設(shè)置正文字體 stsongstdlight是Adobe Reader默認(rèn)字體
> $this->pdf->SetFont('stsongstdlight', '', 14);
# 添加頁(yè)面 該方法如果前面已有頁(yè)面 會(huì)在將頁(yè)腳添加到頁(yè)面中 并自動(dòng)添加下一頁(yè) 否則添加新一頁(yè)
$this->pdf->AddPage();
}
/**
* 生成pdf
* @param $info array
* array(
* 'user'=>'文檔作者' ,
* 'title'=>'文檔標(biāo)題' ,
* 'subject'=>'文檔主題' ,
* 'keywords'=>'文檔關(guān)鍵字' ,
* 'content'=>'文檔正文內(nèi)容' ,
* 'HT'=>'是否開啟頁(yè)眉頁(yè)腳' ,
* 'path'=>'文檔保存路徑');
* @return null
*/
public function createPDF($info = array()) {
if(empty($info) || !is_array($info)) return false;
$this->setDocumentInfo($info['user'] , $info['title'] , $info['subject'] , $info['keywords']);
if(!$info['HT']) {
$this->closeHeaderFooter();
} else {
$this->setHeaderFooter();
}
$this->setMargin();
$this->setMainBody();
# 寫入內(nèi)容
$this->pdf->writeHTML($info['content'], true, false, true, false, '');
# 輸出 I輸出到瀏覽器 F輸出到指定路徑
$this->pdf->Output($info['path'] , 'F');
}
}
結(jié)語(yǔ)
雖然合陵,沒(méi)達(dá)到我預(yù)想的效果,但還是有收獲的澄阳,而且我是第一次看到兩萬(wàn)多行代碼在一個(gè)文件中的PHP文件拥知,有點(diǎn)66的,本來(lái)準(zhǔn)備看看源碼碎赢,學(xué)習(xí)學(xué)習(xí)的低剔,看到代碼后有點(diǎn)發(fā)虛,哈哈肮塞。
END