wkhtmltopdf 導出pdf 樣例

經過2-3天的研究 終於是完成了這項工作,相關經驗記錄一下,興許能幫助一下其他人

環境:Windows+phpStudy  php版本爲5.6.27 框架選擇的是ThinkPHP3.2.3

使用工具 wkhtmltopdf (下載及安裝教程),我的另外一篇有講過這個的使用注意事項,大家可以去看看

php擴展,開啓zip包擴展、PHPExcel擴展  ,沒有這個需求的 可以忽略,php開啓zip擴展:點這裏  貌似php7默認集成了。

來吧 上代碼吧

php文件

IndexController.php

<?php

namespace Admin\Controller {

	use Think\Controller;
	use Admin\Controller\BaseController;
	use Common\Common\Common;

	class IndexController extends BaseController {
		public function index() {
			$this -> display();
		}
		
		
		/**
		 * 上傳並讀取execel
		 */
		public function uploadExcel() {
			set_time_limit ( 0 );
			include('ThinkPHP\Library\Vendor\PHPExcel\Classes\PHPExcel.php');
			include('ThinkPHP\Library\Vendor\PHPExcel\Classes\PHPExcel\IOFactory.php');
			include('ThinkPHP\Library\Vendor\PHPExcel\Reader\Excel2007.php');
			
			
			$upload                         = new \Think\Upload();                  // 實例化上傳類
			$upload -> exts                 = array('xls', 'xlsx');   // 設置附件上傳類型
			$upload -> saveName             = array('uniqid','');
			$upload -> rootPath             = './Public/Upload/';                   // 設置附件上傳根目錄
			$upload -> savePath             = '';                                   // 設置附件上傳(子)目錄
			try{
				$info = $upload-> uploadOne($_FILES['addexcel']);
				if(!$info){
					$errorinfo = $upload->getError();
					echo "<script>parent.callback('".$errorinfo."',false)</script>";
					return;
				}else{
					$url = './Public/Upload/'.$info['savepath'].$info['savename'];
				}
			}
			catch(Exception $e){
				echo "<script>parent.callback('圖片上傳失敗',false)</script>";
				return;
			}
			date_default_timezone_set ( 'PRC' );
			// 讀取excel文件
			try {
				$inputFileType = \PHPExcel_IOFactory::identify ( $url);
				$objReader = \PHPExcel_IOFactory::createReader ( $inputFileType );
				$objReader->setReadDataOnly ( true ); // 只需要添加這個方法實現表格數據格式轉換
				$objPHPExcel = $objReader->load ( $url);
			} catch ( Exception $e ) {
			}
			// 選擇第一個sheet頁
			$sheet = $objPHPExcel->getSheet ( 0 );
			// 獲取當前頁的最大行數
			$highestRow = $sheet->getHighestRow ();
			// 獲取當前頁的最大列數
			$highestColumn = $sheet->getHighestColumn ();
			// 最大列數+1 實際上是往後錯一列
			++$highestColumn;
			$data = array();
			// 第一行一般是表頭【文字類的東西,不需要可以不用管】 這裏從第二行開始取讀取數據
			// 循環行數 獲取數據
			for ($rowIndex = 2; $rowIndex <= $highestRow; $rowIndex++) {
				// 從A列開始循環獲取每個單元格的數據
				for ($colIndex = 'A'; $colIndex != $highestColumn; $colIndex++) {
					$addr = $colIndex . $rowIndex;
					$titlecell = $sheet->getCell($colIndex . '1')->getValue();
					if($titlecell == "exam_date" || $titlecell == "report_date"){
						$cell = $sheet->getCell($addr)->getValue();
						$cell = \PHPExcel_Shared_Date::ExcelToPHP($cell);
						$cell = date("Y年m月d日",$cell);
					}else{
						$cell = $sheet->getCell($addr)->getValue();
					}
					if ($cell instanceof PHPExcel_RichText) { //富文本轉換字符串
						$cell = $cell->__toString();
					}
					if(empty($titlecell)){
						continue ;
					}
					$data[$rowIndex - 2][$titlecell] = $cell;
				}
			}
			// 選擇第二個sheet頁
			$sheet = $objPHPExcel->getSheet ( 1 );
			// 獲取當前頁的最大行數
			$highestRow = $sheet->getHighestRow ();
			// 獲取當前頁的最大列數
			$highestColumn = $sheet->getHighestColumn ();
			// 最大列數+1 實際上是往後錯一列
			++$highestColumn;
			$otherData = array();
			// 第一行一般是表頭【文字類的東西,不需要可以不用管】 這裏從第二行開始取讀取數據
			// 循環行數 獲取數據
			for ($rowIndex = 2; $rowIndex <= $highestRow; $rowIndex++) {
				// 從A列開始循環獲取每個單元格的數據
				for ($colIndex = 'B'; $colIndex != $highestColumn; $colIndex++) {
					$addr = $colIndex . $rowIndex;
					$userNo = $sheet->getCell('A' . $rowIndex)->getValue();
					$titlecell = $sheet->getCell($colIndex . '1')->getValue();
					$cell = $sheet->getCell($addr)->getValue();
					if ($cell instanceof PHPExcel_RichText) { //富文本轉換字符串
						$cell = $cell->__toString();
					}
					if(empty($titlecell)){
						continue ;
					}
					$otherData[$userNo][$titlecell] = $cell;
				}
			}
			$this->createPdfReport($data,$otherData);
		}
		
		public function createPdfReport($rowData,$otherData){
			//$output = shell_exec("D:\Program Flies\wkhtmltopdf\bin\wkhtmltopdf http://www.baidu.com/ ebsite2.pdf");
			//$output = shell_exec("start D:\Program Flies\wkhtmltopdf\bin\wkhtmltopdf.exe");
			//var_dump($output);if($output){echo 'ok';}exit();
			$num = 1;
			$pdfUrl = array();
			foreach ($rowData as $key =>$value){
				// 組裝pdf內容
				$fileName= iconv('utf-8', 'gbk',$value['姓名'].''.$value['檢測編號']);
				$filePath = 'Enclosure/';
				//Common::pdf($this->innerHtml(),$filePath.$fileName);
				file_put_contents($filePath."{$fileName}.html", $this->innerHtml($value,$otherData[$value['檢測編號']]));
				ob_end_clean();
				shell_exec("D:\wkhtmltopdf\bin\wkhtmltopdf.exe --page-size A4  -q -B 0 -L 0 -R 0 -T 0 --no-pdf-compression http://localhost/Enclosure/".$fileName.".html ".$filePath.$fileName.".pdf");
				$pdfUrl[] = $filePath.$fileName.".pdf";
			}
			ob_clean();   //清空但不關閉輸出緩存
			$filename = iconv('utf-8', 'gbk',' pdfReport.zip');//iconv('UTF-8','GBK','4231212_我是中文_1.zip');
			ob_end_clean();
			$zip=new \ZipArchive();
			$ret = $zip->open($filename, \ZipArchive::CREATE);
			foreach ($pdfUrl as $val) {
				$ret1 = $zip->addFile($val);
			}
			$zip->close();
			header('Content-Description: File Transfer');
			Header("content-type:application/x-zip-compressed");
			header('Content-Disposition: attachment; filename='.basename($filename));
			header('Content-Transfer-Encoding: binary');
			header('Expires: 0');
			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
			header('Pragma: public');
			header('Content-Length: ' . filesize($filename));
			ob_clean();   //清空但不關閉輸出緩存
			flush();
			@readfile($filename);
			@unlink($filename);//刪除打包的臨時zip文件。文件會在用戶下載完成後被刪除
			$this->deleteAll(iconv('utf-8', 'gbk',"Enclosure"));//刪除打包的臨時zip文件。文件會在用戶下載完成後被刪除
			exit();
		}
		
		public function innerHtml($exportData,$otherData){
			$html = '<!DOCTYPE html>
			<html lang="en" xmlns="http://www.w3.org/1999/html">
			<head>
			    <meta charset="UTF-8">
			    <title>vip report</title>
			    <link rel="stylesheet" href="../Public/Resources/css/style.css">
			</head>
			<body>
			<section>
			        <!-------------------------報告首頁------------------------->
		    <section class="cont bg-01 pos-relative">
		      
		    </section>
		      <!-------------------------報告詳情封皮------------------------->
		      <section class="cont bg-fengpi pos-relative">  
		        <div class="fengpi-date">
		            <span class="exam-data" id="exam-data">樣本接收日期:'.$exportData['exam_date'].'</span>
		            <span class="report-data" id="report-data">報告日期:'.$exportData['report_date'].'</span>
		        </div>
		        
		        <div class="fengpicode sug-tit tit3">
		                <img class="fengpibarcode" src="../Public/dynamic-graph/'.$exportData['條形碼'].'">
		                <p class="fengpitext">'.$exportData['檢測編號'].'</p>
		        </div>
		        <div class="fengpiinfo">
		                <ul>
		                        <li>
		                            <span>姓名:</span>
		                            <span class="exam-name">'.$exportData['姓名'].'</span>
		                        </li>
		                        <li>
		                            <span>年齡: </span>
		                            <span class="info_phone">'.$exportData['年齡'].'</span>
		                        </li>
		                        <li>
		                            <span>性別: </span>
		                            <span class="info_address">'.$exportData['性別'].'</span>
		                        </li>
		                        <li>
		                            <span>ID: </span>
		                            <span class="info_email">'.$exportData['檢測編號'].'</span>
		                        </li>
		                </ul>
		        </div>
		                
		        
		    </section>
			</body>
			</html>';
			return $html;
		}
	}
}

由於我這次做的是2個sheet頁數據綁定,所以,獲取了兩個sheet頁的東西,大家按需去寫就可以

至於裏面的命令模板  參照如下 ,具體參數給大家一個鏈接:wkhtmltopdf 參數

shell_exec("D:\wkhtmltopdf\bin\wkhtmltopdf.exe --page-size A4  -q -B 0 -L 0 -R 0 -T 0 --no-pdf-compression 1html 1.pdf");

基本上能用到的也沒多少,

–disable-smart-shrinking* 禁止使用WebKit的智能戰略收縮,使像素/ DPI比沒有不變   這個參數可能大家會用到 

innerHtml方法也就把數據綁定到頁面上的方法  至於圖片  css樣式加載不成功的  大家可以直接拼成路徑的形式去找

溫馨提示:這個也不是完全百分之百把網頁顯示樣式轉換成pdf的 ,需要細微的調整,除非你的網頁沒有什麼特別花俏的樣式,慢工出細活,大家慢慢努力,我轉換的頁面高度1403*993 這樣pdf就不會有上下左右的白邊問題,再一個 分頁問題  固定每頁的div 或者section 增加css屬性page-break-inside:avoid;即可。至於有背景圖片的網頁,大家也要慢慢調整哈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章