PHPExcel使用体会
PHPExcel使用体会
因为毕设导师智能分配系统的需要,系负责人在管理学生和导师时,希望可以使用Excel批量导入学生和导师的信息,学长的报课系统使用的是PHPExcel的类库,于是我也抽空花了2天的时间学习了PHPExcel的最基础的导入导出功能的实现,总结了自己的使用心得和一些常用的使用方法
一、类库的引入
PHP我使用的是ThinkPHP5的框架,所以以TP5框架为例,这是项目的PHPExcel的目录结构:
require_once 'extend/reader.php'; //Excel读取
require_once 'extend/PHPExcel_1.8.0_doc/Classes/PHPExcel.php'; //Excel导入导出
二、Excel导入
调用Reader
require_once 'extend/reader.php';
创建Reader
$data = new \Spreadsheet_Excel_Reader();
设置在页面中输出的编码方式
$data->setOutputEncoding('utf-8');
读取上传到当前目录下实际路径为$realPath的文件
$data->read($realPath);
设置PHP的报错级别并返回当前的级别
error_reporting(E_ALL ^ E_NOTICE);
或error_reporting(E_ALL & ~E_NOTICE);
起初并不是很懂这句代码的含义,经过查找资料后发现,在不同的PHP版本中,原本可能在低版本的PHP中运行正常的代码,在较高版本的PHP中运行可能就会出现报错,为了使程序能够正常运行,需要在程序开头加上这句代码;error_reporting()设置PHP的报错级别并返回当前的级别,以下是网络上查找的一些资料,在做Excel导出的时候出现了一个bug很久都没有解决,在TP5的交流群询问之后被某位大佬问到:“你知道PHP的报错等级吗?你知道什么是未定义变量吗?”查看错误报告之后发现确实出现了下面的第7条错误:
- 错误报告是按位的。或者将数字加起来得到想要的错误报告等级
- E_ALL - 所有的错误和警告
- E_ERROR - 致命性运行时错
- E_WARNING - 运行时警告(非致命性错)
- E_PARSE - 编译时解析错误
- E_NOTICE - 运行时提醒
- 可能是有意的行为造成的(如:基于未初始化的变量自动初始化为一个空字符串的事实而使用一个未初始化的变量)
- E_CORE_ERROR - 发生于PHP启动时初始化过程中的致命错误
- E_CORE_WARNING - 发生于PHP启动时初始化过程中的警告(非致命性错)
- E_COMPILE_ERROR - 编译时致命性错
- E_COMPILE_WARNING - 编译时警告(非致命性错)
- E_USER_ERROR - 用户产生的出错消息
- E_USER_WARNING - 用户产生的警告消息
- E_USER_NOTICE - 用户产生的提醒消息
循环处理Excel表格里的每一行数据并插入数据库
for ($i=3; $i <=$data->sheets[0]['numRows'] ; $i++) {
$insert = [];
$insert['grade'] = $data->sheets[0]['cells'][$i][1];
$insert['serialNum'] = $data->sheets[0]['cells'][$i][2];
$insert['password'] = $data->sheets[0]['cells'][$i][2];
$insert['name'] = $data->sheets[0]['cells'][$i][3];
$insert['gender'] = $data->sheets[0]['cells'][$i][4];
$insert['college'] = $data->sheets[0]['cells'][$i][5];
$insert['department'] = $data->sheets[0]['cells'][$i][6];
$insert['gpa'] = $data->sheets[0]['cells'][$i][7];
$insert['rank'] = $data->sheets[0]['cells'][$i][8];
$insert['telephone'] = $data->sheets[0]['cells'][$i][9];
$insert['chosen'] = 0;
//插入数据库中
Db('user_student_'.$insert['grade'])->insert($insert);
}
三、Excel导出
引入PHPExcel.php
require_once 'extend/PHPExcel_1.8.0_doc/Classes/PHPExcel.php';
创建一个新的Excel文件
$excel = new \PHPExcel();
先进行一般的Excel格式的处理
$excel->getActiveSheet()->getColumnDimension('A')->setWidth(9); //手动设置单元格宽度
$excel->getActiveSheet()->getColumnDimension('B')->setWidth(30);
$excel->getActiveSheet()->getColumnDimension('C')->setWidth(9); $excel->getActiveSheet()->getRowDimension(2)->setRowHeight(35); //设置某一行高度 $excel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); //设置水平居中
$excel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); //设置水平居中 $excel->getActiveSheet()->getStyle('G')->getNumberFormat()->setFormatCode('000000000'); //设置文本格式 //设置边框和水平垂直居中,PHPExcel貌似没有对所有的单元格进行统一处理的功能,所以我定义里一个$styleArray,方便在往Excel中写入数据时,同时对单元格进行格式的设置
$styleArray = [
'alignment' => [
'horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
'vertical' => \PHPExcel_Style_Alignment::VERTICAL_CENTER
],
'borders' => [
'allborders' => [
'style' => \PHPExcel_Style_Border::BORDER_THIN
]
]
];
$excel->getActiveSheet()->getStyle('A1')->applyFromArray($styleArray); $excel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true); //设置字体加粗 $excel->getActiveSheet()->mergeCells('A1:H1'); //合并A1:F1单元格
对表格第一行标题的特殊处理
$excel->getActiveSheet()->mergeCells('A1:H1'); //合并A1:H1单元格
$excel->getActiveSheet()->setCellValue('A1',$insert[0]['grade'].'级'.$insert[0]['dep'].'导师分配结果');
$excel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true); //加粗
$excel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); //设置水平居中
$excel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); //设置垂直居中
对表的标题行的特殊处理
$letter = ['A','B','C','D','E','F','G','H'];
$tableHeader = ['序号','系别','专业导师','职称','课题','学生姓名','学号','联系方式']; //设置表头数组,单独处理
for ($i=0; $i <8 ; $i++) {
$excel->getActiveSheet()->setCellValue($letter[$i].'2',$tableHeader[$i]); //设置单元格的值
$excel->getActiveSheet()->getStyle($letter[$i].'2')->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
$excel->getActiveSheet()->getStyle($letter[$i].'2')->getFont()->setBold(true); //设置单元格字体加粗
}
在这次项目中碰到的比较奇葩的问题和处理办法 - 某些单元格的动态合并:
第一种情况
如上图,对于上图这种格式的Excel写入是比较简单的,只需从数据库中取出数据,逐条的插入进表格中,并作格式处理就好了$totalInsert = count($insert); //计算总插入数
for ($i=0; $i <$totalInsert ; $i++) {
$excel->getActiveSheet()->setCellValue('A'.($i+3),($i+1));
$excel->getActiveSheet()->setCellValue('B'.($i+3),$insert[$i]['tdep']);
$excel->getActiveSheet()->setCellValue('C'.($i+3),$insert[$i]['sname']);
$excel->getActiveSheet()->setCellValue('D'.($i+3),$insert[$i]['snum']);
$excel->getActiveSheet()->setCellValue('E'.($i+3),$insert[$i]['stele']);
$excel->getActiveSheet()->setCellValue('F'.($i+3),$insert[$i]['tname']);
$excel->getActiveSheet()->setCellValue('G'.($i+3),$insert[$i]['tposi']);
$excel->getActiveSheet()->setCellValue('H'.($i+3),$insert[$i]['title']);
$excel->getActiveSheet()->setCellValue('I'.($i+3),$insert[$i]['ttele']);
} for ($j=0; $j <9 ; $j++) {
$excel->getActiveSheet()->getStyle($letter[$j].'3'.':'.$letter[$j].($totalInsert+2))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
}
第二种情况
如上图,对于初学PHPExcel的我来说,上图的操作简直是麻烦,我的做法是先设置两个临时变量
$oldTemp
和$newTemp
用来处理合并的单元格的范围,例如合并A1:A6,$oldTemp
用来记录合并的左范围,$newTemp
用来记录合并的右范围,并且$newTemp = $oldTemp + 每个导师的学生数
,若学生数为0,则加1先插入列F、G、H的数据,加样式,然后对前面的列A、B、C、D、E先插值,再进行单元格合并,因为比如A1:A3合并,合并后的单元格名称仍然为A1,合并的范围为
$oldTemp : $newTemp-1
,然后交换$oldTemp
和$newTemp
不知道有没有更好的处理办法,对自己的处理办法表示有点愚蠢。。
$oldTemp = 3; //临时变量,用于处理合并单元格的范围
$newTemp = 0; //临时变量,用于处理合并单元格的范围 for ($i=0; $i <$totalInsert ; $i++) { //循环插入数据,并作格式处理
if ($insert[$i]['stuNum'] == 0) { //判断导师是否有学生,如果没有学生,只需插入一行
$tempCount = $insert[$i]['stuNum'] + 1;
} else {
$tempCount = $insert[$i]['stuNum'];
}
for ($j=0; $j <$tempCount ; $j++) { //开始插入
if ($insert[$i]['stuNum'] != 0) { //逐一插入导师的学生信息
$excel->getActiveSheet()->setCellValue('F'.($j+$oldTemp),$insert[$i]['tstudentL'][$j]['sname']);
$excel->getActiveSheet()->setCellValue('G'.($j+$oldTemp),$insert[$i]['tstudentL'][$j]['snum']);
$excel->getActiveSheet()->setCellValue('H'.($j+$oldTemp),$insert[$i]['tstudentL'][$j]['stele']);
} $excel->getActiveSheet()->getStyle('F'.($j+$oldTemp))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
$excel->getActiveSheet()->getStyle('G'.($j+$oldTemp))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
$excel->getActiveSheet()->getStyle('H'.($j+$oldTemp))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
} $excel->getActiveSheet()->setCellValue('A'.$oldTemp,($i+1)); //设置单元格的值
$excel->getActiveSheet()->setCellValue('B'.$oldTemp,$insert[$i]['dep']);
$excel->getActiveSheet()->setCellValue('C'.$oldTemp,$insert[$i]['tname']);
$excel->getActiveSheet()->setCellValue('D'.$oldTemp,$insert[$i]['position']);
$excel->getActiveSheet()->setCellValue('E'.$oldTemp,$insert[$i]['title']); $newTemp = $oldTemp + $tempCount;
if ($insert[$i]['stuNum'] != 1 && $insert[$i]['stuNum'] != 0) {
for ($k=0; $k <5 ; $k++) {
$excel->getActiveSheet()->mergeCells($letter[$k].$oldTemp.':'.$letter[$k].($newTemp-1)); //根据导师的学生数合并A、B、C、D、E列的单元格
}
} for ($z=0; $z <5 ; $z++) {
$excel->getActiveSheet()->getStyle($letter[$z].$oldTemp.':'.$letter[$z].($newTemp-1))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
} $oldTemp = $newTemp;
}
直接输出至浏览器,即下载至本地,只需直接加入代码就行
$write = new \PHPExcel_Writer_Excel5($excel);
header("Pragma: public");
header("Expires: 0");
header("Cache-Control:must-revalidate, post-check=0, pre-check=0");
header("Content-Type:application/force-download");
header("Content-Type:application/vnd.ms-execl");
header("Content-Type:application/octet-stream");
header("Content-Type:application/download");;
header('Content-Disposition:attachment;filename='.'"'.$insert[0]['grade'].'级导师互选结果.xls"'); //可以对文件名进行处理
header("Content-Transfer-Encoding:binary");
$write->save('php://output');
四、实践效果动图
学生Excel导入:
Excel模版导出:
结果导出:
五、总结
期间遇到了很多的bug,不断的上网找资料、找博客,学到了很多的知识,比如在一个''上刚了非常多的时间,最后找到错误的时候又喜又气的,还有在往Excel中写数据的时候,碰到一个未定义数组下标[0]的错误的时候,花了更多的时间,反反复复的检查代码愣是没发现错误在哪里,躺在床上没解决bug不甘心又下床苦寻,最后发现数据库中的数据有一些是空的,直接插入会出错,要做一些相应的处理
学到了新知识心里是惊喜的,不过我也是得去做下编译实验的。。
PHPExcel使用体会的更多相关文章
- phpexcel读取输出操作
//读取 <?php header("Content-Type:text/html;charset=utf-8"); include 'Classes/PHPExcel.ph ...
- [moka同学笔记]PHPexcel之excel导出和导入
原案例来自http://www.sucaihuo.com/有修改 1.目录结构(文件不用解释,应该都可以看得懂,直接看代码)
- phpexcel导出数据表格
1.下载phpexcel(李昌辉) 2.在页面引入phpexcel的类文件,并且造该类的对象 include("../chajian/phpexcel/Classes/PHPExcel.ph ...
- phpexcel 字符串转码
问题状况:在导入excel的时候会出现 PHPExcel_RichText Object ( [_richTextElements:PHPExcel_RichText:] => PHPExcel ...
- thinkphp3.2和phpexcel导入
先整个最基础的代码,理解了这个,后面的就非常简单了 $file_name= './Upload/excel/123456.xls'; import("Org.Util.PHPExcel&qu ...
- PHPExcel 大数据的导出
PHPExcel 是一个php语言读取导出数据.导入生成Excel的类库,使用起来非常方便,但有时会遇到以些问题,比如导出的数据超时,内存溢出等. 下面我们来说说这些问题和解决办法. PHPExcel ...
- PHPExcel按单元格读取数据
import('ORG.Util.PHPExcel.PHPExcel'); $objReader = new PHPExcel_Reader_Excel2007(); //use excel2007 ...
- phpexcel读取excel的xls xlsx csv格式
我之前写过一篇PHP读取csv文件的内容 上代码index.php <?php /** * * @author XC * */ class Excel { public $currentShee ...
- 解决 PHPExcel 长数字串显示为科学计数
解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. ...
随机推荐
- 面向对象的PHP
类的实例(包括继承) <?php // 父类 class Animal { public $name; public $age; // 构造函数,使用new操作符生成实例的时候自动调用 func ...
- IT人员如何保护视力
最近感觉眼比较难受,有点干,估计是因为用上老婆淘汰的iPhone5C后屏幕太小,而我又是一个手机瘾重点患者的原因.为了保持自己5.0+的视力,做了以下工作,分享给各位朋友: Win7电脑将字体放大到1 ...
- C# WinForm应用程序降低系统内存占用方法
这里整理了一些网上关于Winform如何降低系统内存占用的资料,供参考: 1.使用性能测试工具dotTrace 3.0,它能够计算出你程序中那些代码占用内存较多2.强制垃圾回收3.创建完对象实例后,记 ...
- arguments.callee 调用自身 caller,callee,apply and call
一.Arguments该对象代表正在执行的函数和调用他的函数的参数.[function.]arguments[n]参数function :选项.当前正在执行的 Function 对象的名字.n :选项 ...
- 在Word2013中多次应用格式刷
顾名思义,格式刷是为了方便需要跨区域操作时候,能快速的应用格式到相应文本.那么怎么使用word进行格式刷的多次使用呢.我们先来看单次的,这个比较容易,只要在先需要的格式单击一次格式刷,再到需要的文本执 ...
- 我的第一个jsp程序-实现注册登录留言功能
1,注册功能,包括两个页面 zhuce.jsp注册页面 <%@ page language="java" contentType="text/html; chars ...
- tomcat报错
错误日志如下: 十月 10, 2016 10:44:57 上午 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.serv ...
- NHibernate中session.update()及session.merge()的区别
今天的工作中遇到一个奇怪的问题,如下: "a different object with the same identifier value was already associated w ...
- js-字符串转化日期
endLogTimeDate = “2012-05-22 17:10:46” startLogTimeDate = “2012-05-22 17:10:46” var endLogTimeDate = ...
- HTML常用标签与表格标签
超链接标签: <a href="超链接地址" target="_blank">超链接的文字</a> _blank或new是在新网页中打开 ...