PHP生成PDF並轉換成圖片爬過的坑
需求描述:根據訂單通過模板合同生成新的PDF合同通過e籤寶簽約後轉為圖片給使用者下載。
需求整理:
1.如何生成PDF檔案:使用TCPDF擴充套件生成。思考:
⑴為了方便將模板中的固定佔位符替換為訂單中的內容,使用靜態html頁面儲存合同模板的方式儲存
⑵使用TCPDF將html轉換為pdf文件,可以儘量保證合同格式的一致性
2.將生成的PDF合同通過e籤寶的簽約流程進行圖章簽署。具體流程忽略:對比e籤寶簽約流程
3.將簽約後的新PDF合同轉換為圖片。思考:
⑴使用php的Imagick擴充套件實現(坑之所在)
實現流程:
1.安裝TCPDF擴充套件,這個都是原生的PHP程式碼庫比較簡單,依賴composer。在要安裝的目錄命令列直接敲:
composer require smalot/pdfparser
2.安裝Imagick擴充套件,這個流程比較多。可以參考下面連結(感謝感謝):
https://www.cnblogs.com/jinxiblog/p/8053008.html --windows環境安裝(我是windows開發環境,使用這個沒毛病)
https://www.osyunwei.com/archives/5327.html --linux環境安裝(沒測試過,留給以後測試)
https://blog.csdn.net/webben/article/details/64125470 --linux環境安裝(沒測試過,留給以後測試)
3.第一個坑,Imagick裝好就行了嗎?並不然,網上找了很多資料後表面Imagick的執行機制大概是php通過Imagick擴充套件呼叫本機安裝的Imagemagic提供的介面來處理圖片,另外如果你要readImage的是一個PDF檔案那麼還有一個前提就是Imagemagic應用本身還會呼叫ghostscript這個玩意。
因為我們的需求是將PDF轉換為圖片而不是普通的圖片檔案處理,所以ghostscript也是我們必須要安裝的。linux下同理。如果沒安裝的話會出現諸如下面的錯誤:
Postscript delegate failed `/Uploads/Download/2016-09/57d0fb5b3612d.pdf': No such file or directory @ error/pdf.c/ReadPDFImage/664
看看Imagick下面官方說明:
4.安裝ghostscript,官網上根據自己的環境下載不同安裝包,如果phpinfo()中的php是X86的話記得要選32位的安裝包下載,裝完後記得重啟。本人重啟了n次才突然間成功
https://www.ghostscript.com/download.html --下載連結
5.到這裡基本的依賴已經安裝完畢,貼下本地實驗程式碼如下:
require_once 'vendor/autoload.php';
//PDF檔案生成 $tcpdf = new TCPDF(); $tcpdf->SetCreator('Hello'); $tcpdf->SetAuthor('walter'); $tcpdf->SetTitle('test pdf'); $tcpdf->SetSubject('subject'); $tcpdf->SetKeywords('walter,pdf,php'); $tcpdf->setHeaderData('logo_example.png',20,'標題','子標題',array(0,64,255),array(0,64,128)); $tcpdf->setFooterData(array(0,64,0),array(0,64,128)); $tcpdf->setHeaderFont(['stsongstdlight', '', '10']); //設定字型 $tcpdf->setFooterFont(['helvetica', '', '8']); //設定字型 $tcpdf->SetDefaultMonospacedFont('courier'); //設定字型 $tcpdf->SetMargins(15,27,15); $tcpdf->setHeaderMargin(5); $tcpdf->setFooterMargin(10); $tcpdf->SetAutoPageBreak(true,25); $tcpdf->setImageScale(1.25); $tcpdf->setFontSubsetting(true); $tcpdf->SetFont('stsongstdlight','',14); //設定字型 // $tcpdf->AddPage(); $html = file_get_contents('contract.html'); $tcpdf->writeHTMLCell(0,0,'','',$html,0,1,0,true,'',true); //寫入html $tcpdf->Output(__DIR__.DIRECTORY_SEPARATOR.'contract.pdf','F'); //生成pdf檔案並儲存到本地 //pdf合併轉換一張圖片 function pdf2png($from_path,$target_path){ try{ $img = new Imagick(); $img->setCompressionQuality(100); $img->setResolution(120,120); $img->readImage($from_path); $canvas = new Imagick(); $imgNum = $img->getNumberImages(); foreach ($img as $k => $sub){ $sub->setImageFormat('png'); $sub->stripImage(); $sub->trimImage(0); $width = $sub->getImageWidth() + 10; $height = $sub->getImageHeight() + 10; if ($k + 1 == $imgNum) $height += 10; $canvas->newImage($width,$height,new ImagickPixel('white')); $canvas->compositeImage($sub,Imagick::COMPOSITE_DEFAULT,5,5); } $canvas->resetIterator(); $canvas->appendImages(true)->writeImage($target_path); return true; }catch (Exception $e){ echo $e->getMessage(); echo $e->getTraceAsString(); return false; } //pdf檔案轉換為一張圖片 $pdf_path = __DIR__.DIRECTORY_SEPARATOR.'contract.pdf'; if (is_file($pdf_path)){ var_dump(pdf2png($pdf_path,__DIR__.DIRECTORY_SEPARATOR.'contract.png')); }else{ echo 'file not exist'; }
至此本地測試沒毛病一切OK
PDF檔案 生成的圖片
6.正式伺服器上測試(最大的坑來了),生成PDF檔案一切OK,到了轉換圖片的時候就:
一遍空白!!!!!!神坑
一遍度娘亂七八糟的資料後發現根本沒有這方面的資料。偶爾在百度提問裡面看到有人又類似說法是,Imagick->readImage的時候中文編碼的問題。雖然不太對但是在萬能的stackoverflow有人提過類似的問題
經過不停的踩坑發現是ghostscript這個坑貨的問題,在linux下安裝ghostscript的時候沒有對應生成cidfmap檔案來支援各種字型,在windows環境安裝的時候已經在lib目錄下面生成了這個配置檔案。所以需要在linux環境下新建一個cidfmap檔案並且將我們要支援的字型放到linux下來:
http://www.voidcn.com/article/p-fdqtdali-rx.html --參考連結
這樣就行了嗎?還沒有.......看看程式碼裡面我生成pdf時設定了什麼字型?這些是adobe公司預設的字型,但是比較不統一。你程式碼裡面要設什麼字型就得把對應的ttf字型檔案放到linux下重新對應cidfmap的字型格式設定一遍。
$tcpdf->SetFont('stsongstdlight','',14); $tcpdf->setHeaderFont(['stsongstdlight', '', '10']); $tcpdf->setFooterFont(['helvetica', '', '8']); $tcpdf->SetDefaultMonospacedFont('courier');
為了避免麻煩我在windows的字型庫裡面拿了一個simhei字型(簡體字)放到linux下配置好,最後發現這個字型不是TCPDF擴充套件內建的(坑)。還好tcpdf庫提供了一個新增字型的指令碼,具體路徑如下:
把要新增的simhei字型放進來命令列輸入如下命令:
#\tools>php ./tcpdf_addfont.php -b -i simhei.ttf >>> Converting fonts for TCPDF: *** Output dir set to D:\phpStudy2016\WWW\mugua\muguaadmin\public\task\pdf\vendo r\tecnickcom\tcpdf/fonts/ +++ OK : D:\phpStudy2016\WWW\mugua\muguaadmin\public\task\pdf\vendor\tecnickco m\tcpdf\tools\simhei.ttf added as simhei >>> Process successfully completed!
恭喜你,爬坑完畢字型終於可以正常使用,生成的圖片再也不是空白了