经过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;即可。至于有背景图片的网页,大家也要慢慢调整哈
作者:董金锁
原文链接:https://blog.csdn.net/u011713224/article/details/90518707
转载请注明:www.ainoob.cn » wkhtmltopdf 导出pdf 样例