經過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;即可。至於有背景圖片的網頁,大家也要慢慢調整哈