多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 依赖库 大名鼎鼎的phpexcel <http://phpexcel.codeplex.com> ## 效果 ![](https://box.kancloud.cn/2015-11-28_56597975de34b.png) ![](https://box.kancloud.cn/2015-11-28_565979760cca9.png) ![](https://box.kancloud.cn/2015-11-28_565979761f10f.png) ![](https://box.kancloud.cn/2015-11-28_5659797636177.png) ![](https://box.kancloud.cn/2015-11-28_565979764a158.png) 是用方法就是后台初始化report数据库后,然后自己建好数据表。 然后新建模板->上传一个excel模板,指定好查询的数据,和填充的开始项。然后数据随便后台操作数据库。前台就是把excel报表显示输出来即可。 感谢写好这个系统的吴学海同学。其实数据填充那步相当于excel软件导入的数据源。 这套模板管理系统支持多子excel和对应多数据源。组合起来不是特别复杂的excel报表都能满足。 像第一个签到模板,我的excel模板![](https://box.kancloud.cn/2015-11-28_56597976593e4.png),excel中的竖线自己设格式。 然后我的数据源,![](https://box.kancloud.cn/2015-11-28_565979766671d.png) 就是序列化字段里的那个 select name,time from sign limit 10。然后开始位置是每行的第一个单元格德位置如 A2 表示第二行第一列。 要更完善的话,就是数据源支持选api就更好了。配置最好用json 可读性更高 ## 实现 随书项目yang_book/examples/excel里。 我们只看excel的相关代码: 前台具体显示某一个模板的excel ~~~ /** * 查询数据库填充excel并展示为html。 * @throws \PHPExcel_Exception * @throws \PHPExcel_Reader_Exception * @throws \PHPExcel_Writer_Exception */ public function showReport(){ //是否导出 $export = I('export',0,'int'); $id = I('report_id',0,'int'); if(!$id){ $this->error('参数有误'); } $reportInfo = M('report')->where(array('id'=>$id))->find(); //导入第三方类 import("Vendor.PHPExcel"); import("Vendor.PHPExcel.Reader.Excel2007"); import("Vendor.PHPExcel.Reader.Excel5"); import("Vendor.PHPExcel.Reader.HTML"); import("Vendor.PHPExcel.Writer.Excel2007"); import("Vendor.PHPExcel.Writer.CSV"); import("Vendor.PHPExcel.IOFactory"); $totalPHPExcel = []; $tempInfo = unserialize($reportInfo['tempinfo']); foreach($tempInfo as $k=>$va){ $PHPReader = new \PHPExcel_Reader_Excel2007(); if(!$PHPReader->canRead('./Uploads/template'.$va['path'])){ $PHPReader = new \PHPExcel_Reader_Excel5(); if(!$PHPReader->canRead('./Uploads/template'.$va['path'])){ $this->error('该excel模板无法读取。请联系管理员'); return ; } } //读取模板 $PHPExcel = $PHPReader->load('./Uploads/template'.$va['path']); $currentSheet = $PHPExcel->getSheet(0); foreach($va['config'] as $cnf){ //根据配置信息,查询数据 $sql = $cnf['sql']; $start_x = preg_split("/([a-zA-Z]+)/", $cnf['start_x'], 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); if(empty($sql)){ break; $this->error('sql错误'); } $data = M()->query($sql); //row坐标计数器 $i = 0; foreach($data as $v){ if(is_array($v) && !empty($v)){ $AZ = strtoupper($start_x[0]); //循环填充数据 foreach($v as $value){ $currentSheet->setCellValue($AZ.($start_x[1]+$i),$value); $objStyleA1 = $currentSheet->getStyle($AZ.($start_x[1]+$i)); $objAlignA1 = $objStyleA1->getAlignment(); $objAlignA1->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); $AZ = $this->nextAZ($AZ); if(!$AZ){ $this->error('A-Z超值,请联系管理员'); } } } $i++; } } if(!$export){ //显示模板 $objWriteHTML =new \PHPExcel_Writer_HTML($PHPExcel); $objWriteHTML->save("php://output"); }else{ $objWrite = new \PHPExcel_Writer_Excel2007($PHPExcel); $objWrite->save ($k.'.xls'); $totalPHPExcel[] = $k.'.xls'; } } //excel文件导出,所有模板打包一起下载 if($export){ @unlink(iconv("UTF-8","gbk//TRANSLIT",$reportInfo['name'].'.zip')); $zip = new \ZipArchive(); if($zip->open(iconv("UTF-8","gbk//TRANSLIT",$reportInfo['name'].'.zip'),\ZipArchive::OVERWRITE) === true){ foreach($totalPHPExcel as $v){ $zip->addFile($v); } } $zip->close(); //下面是输出下载; header ( "Cache-Control: max-age=0" ); header ( "Content-Description: File Transfer" ); header ( 'Content-disposition: attachment; filename=' . basename (iconv("UTF-8","gbk//TRANSLIT",$reportInfo['name'].'.zip')) ); // 文件名 header ( "Content-Type: application/zip" ); // zip格式的 header ( "Content-Transfer-Encoding: binary" ); header ( 'Content-Length: ' . filesize (iconv("UTF-8","gbk//TRANSLIT",$reportInfo['name'].'.zip') ) ); // 告诉浏览器,文件大小 @readfile ( iconv("UTF-8","gbk//TRANSLIT",$reportInfo['name'].'.zip'));//输出文件; } } ~~~ 类私有方法nextAZ: ~~~ /** * 返回下一个字母 * @param $currAZ * @return bool */ private function nextAZ($currAZ){ $defaultAZ = array( 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' ); $countLength = count($currAZ); if($countLength > 1){ //TODO:大于1位未实现 substr($currAZ,-1,1); return false; }else{ if($currAZ != 'Z'){ $index = array_search($currAZ,$defaultAZ); return $defaultAZ[$index+1]; }else{ //TODO:超过Z未实现 return false; } } } ~~~ 大家具体看看 主要是用了excel的打开模板`$PHPReader->load`、遍历填值`$currentSheet->setCellValue($AZ.($start_x[1]+$i),$value);` 还有下载文件和压缩下载 ## 参考 <http://www.seo0395.com/archives-211>介绍的比较全,英文不好的可以看看,好的直接看官方文档 <https://github.com/PHPOffice/PHPExcel/wiki/User%20Documentation>