PHPExcel使用体会

  1. 因为毕设导师智能分配系统的需要,系负责人在管理学生和导师时,希望可以使用Excel批量导入学生和导师的信息,学长的报课系统使用的是PHPExcel的类库,于是我也抽空花了2天的时间学习了PHPExcel的最基础的导入导出功能的实现,总结了自己的使用心得和一些常用的使用方法

一、类库的引入

  • PHP我使用的是ThinkPHP5的框架,所以以TP5框架为例,这是项目的PHPExcel的目录结构:

    1. require_once 'extend/reader.php'; //Excel读取
    2. require_once 'extend/PHPExcel_1.8.0_doc/Classes/PHPExcel.php'; //Excel导入导出

二、Excel导入

  • 调用Reader

    1. require_once 'extend/reader.php';
  • 创建Reader

    1. $data = new \Spreadsheet_Excel_Reader();
  • 设置在页面中输出的编码方式

    1. $data->setOutputEncoding('utf-8');
  • 读取上传到当前目录下实际路径为$realPath的文件

    1. $data->read($realPath);
  • 设置PHP的报错级别并返回当前的级别

    1. error_reporting(E_ALL ^ E_NOTICE);
    2. error_reporting(E_ALL & ~E_NOTICE);

    起初并不是很懂这句代码的含义,经过查找资料后发现,在不同的PHP版本中,原本可能在低版本的PHP中运行正常的代码,在较高版本的PHP中运行可能就会出现报错,为了使程序能够正常运行,需要在程序开头加上这句代码;error_reporting()设置PHP的报错级别并返回当前的级别,以下是网络上查找的一些资料,在做Excel导出的时候出现了一个bug很久都没有解决,在TP5的交流群询问之后被某位大佬问到:“你知道PHP的报错等级吗?你知道什么是未定义变量吗?”查看错误报告之后发现确实出现了下面的第7条错误:

    1. 错误报告是按位的。或者将数字加起来得到想要的错误报告等级
    2. E_ALL - 所有的错误和警告
    3. E_ERROR - 致命性运行时错
    4. E_WARNING - 运行时警告(非致命性错)
    5. E_PARSE - 编译时解析错误
    6. E_NOTICE - 运行时提醒
    7. 可能是有意的行为造成的(如:基于未初始化的变量自动初始化为一个空字符串的事实而使用一个未初始化的变量)
    8. E_CORE_ERROR - 发生于PHP启动时初始化过程中的致命错误
    9. E_CORE_WARNING - 发生于PHP启动时初始化过程中的警告(非致命性错)
    10. E_COMPILE_ERROR - 编译时致命性错
    11. E_COMPILE_WARNING - 编译时警告(非致命性错)
    12. E_USER_ERROR - 用户产生的出错消息
    13. E_USER_WARNING - 用户产生的警告消息
    14. E_USER_NOTICE - 用户产生的提醒消息
  • 循环处理Excel表格里的每一行数据并插入数据库

    1. for ($i=3; $i <=$data->sheets[0]['numRows'] ; $i++) {
    2. $insert = [];
    3. $insert['grade'] = $data->sheets[0]['cells'][$i][1];
    4. $insert['serialNum'] = $data->sheets[0]['cells'][$i][2];
    5. $insert['password'] = $data->sheets[0]['cells'][$i][2];
    6. $insert['name'] = $data->sheets[0]['cells'][$i][3];
    7. $insert['gender'] = $data->sheets[0]['cells'][$i][4];
    8. $insert['college'] = $data->sheets[0]['cells'][$i][5];
    9. $insert['department'] = $data->sheets[0]['cells'][$i][6];
    10. $insert['gpa'] = $data->sheets[0]['cells'][$i][7];
    11. $insert['rank'] = $data->sheets[0]['cells'][$i][8];
    12. $insert['telephone'] = $data->sheets[0]['cells'][$i][9];
    13. $insert['chosen'] = 0;
    14. //插入数据库中
    15. Db('user_student_'.$insert['grade'])->insert($insert);
    16. }

三、Excel导出

  • 引入PHPExcel.php

    1. require_once 'extend/PHPExcel_1.8.0_doc/Classes/PHPExcel.php';
  • 创建一个新的Excel文件

    1. $excel = new \PHPExcel();
  • 先进行一般的Excel格式的处理

    1. $excel->getActiveSheet()->getColumnDimension('A')->setWidth(9); //手动设置单元格宽度
    2. $excel->getActiveSheet()->getColumnDimension('B')->setWidth(30);
    3. $excel->getActiveSheet()->getColumnDimension('C')->setWidth(9);
    4. $excel->getActiveSheet()->getRowDimension(2)->setRowHeight(35); //设置某一行高度
    5. $excel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); //设置水平居中
    6. $excel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); //设置水平居中
    7. $excel->getActiveSheet()->getStyle('G')->getNumberFormat()->setFormatCode('000000000'); //设置文本格式
    8. //设置边框和水平垂直居中,PHPExcel貌似没有对所有的单元格进行统一处理的功能,所以我定义里一个$styleArray,方便在往Excel中写入数据时,同时对单元格进行格式的设置
    9. $styleArray = [
    10. 'alignment' => [
    11. 'horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
    12. 'vertical' => \PHPExcel_Style_Alignment::VERTICAL_CENTER
    13. ],
    14. 'borders' => [
    15. 'allborders' => [
    16. 'style' => \PHPExcel_Style_Border::BORDER_THIN
    17. ]
    18. ]
    19. ];
    20. $excel->getActiveSheet()->getStyle('A1')->applyFromArray($styleArray);
    21. $excel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true); //设置字体加粗
    22. $excel->getActiveSheet()->mergeCells('A1:H1'); //合并A1:F1单元格
  • 对表格第一行标题的特殊处理

    1. $excel->getActiveSheet()->mergeCells('A1:H1'); //合并A1:H1单元格
    2. $excel->getActiveSheet()->setCellValue('A1',$insert[0]['grade'].'级'.$insert[0]['dep'].'导师分配结果');
    3. $excel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true); //加粗
    4. $excel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); //设置水平居中
    5. $excel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); //设置垂直居中
  • 对表的标题行的特殊处理

    1. $letter = ['A','B','C','D','E','F','G','H'];
    2. $tableHeader = ['序号','系别','专业导师','职称','课题','学生姓名','学号','联系方式']; //设置表头数组,单独处理
    3. for ($i=0; $i <8 ; $i++) {
    4. $excel->getActiveSheet()->setCellValue($letter[$i].'2',$tableHeader[$i]); //设置单元格的值
    5. $excel->getActiveSheet()->getStyle($letter[$i].'2')->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
    6. $excel->getActiveSheet()->getStyle($letter[$i].'2')->getFont()->setBold(true); //设置单元格字体加粗
    7. }
  • 在这次项目中碰到的比较奇葩的问题和处理办法 - 某些单元格的动态合并:

    第一种情况如上图,对于上图这种格式的Excel写入是比较简单的,只需从数据库中取出数据,逐条的插入进表格中,并作格式处理就好了

    1. $totalInsert = count($insert); //计算总插入数
    2. for ($i=0; $i <$totalInsert ; $i++) {
    3. $excel->getActiveSheet()->setCellValue('A'.($i+3),($i+1));
    4. $excel->getActiveSheet()->setCellValue('B'.($i+3),$insert[$i]['tdep']);
    5. $excel->getActiveSheet()->setCellValue('C'.($i+3),$insert[$i]['sname']);
    6. $excel->getActiveSheet()->setCellValue('D'.($i+3),$insert[$i]['snum']);
    7. $excel->getActiveSheet()->setCellValue('E'.($i+3),$insert[$i]['stele']);
    8. $excel->getActiveSheet()->setCellValue('F'.($i+3),$insert[$i]['tname']);
    9. $excel->getActiveSheet()->setCellValue('G'.($i+3),$insert[$i]['tposi']);
    10. $excel->getActiveSheet()->setCellValue('H'.($i+3),$insert[$i]['title']);
    11. $excel->getActiveSheet()->setCellValue('I'.($i+3),$insert[$i]['ttele']);
    12. }
    13. for ($j=0; $j <9 ; $j++) {
    14. $excel->getActiveSheet()->getStyle($letter[$j].'3'.':'.$letter[$j].($totalInsert+2))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
    15. }

    第二种情况如上图,对于初学PHPExcel的我来说,上图的操作简直是麻烦,我的做法是

    1. 先设置两个临时变量 $oldTemp$newTemp 用来处理合并的单元格的范围,例如合并A1:A6,$oldTemp 用来记录合并的左范围,$newTemp用来记录合并的右范围,并且 $newTemp = $oldTemp + 每个导师的学生数,若学生数为0,则加1

    2. 先插入列F、G、H的数据,加样式,然后对前面的列A、B、C、D、E先插值,再进行单元格合并,因为比如A1:A3合并,合并后的单元格名称仍然为A1,合并的范围为 $oldTemp : $newTemp-1,然后交换 $oldTemp$newTemp

    3. 不知道有没有更好的处理办法,对自己的处理办法表示有点愚蠢。。

      1. $oldTemp = 3; //临时变量,用于处理合并单元格的范围
      2. $newTemp = 0; //临时变量,用于处理合并单元格的范围
      3. for ($i=0; $i <$totalInsert ; $i++) { //循环插入数据,并作格式处理
      4. if ($insert[$i]['stuNum'] == 0) { //判断导师是否有学生,如果没有学生,只需插入一行
      5. $tempCount = $insert[$i]['stuNum'] + 1;
      6. } else {
      7. $tempCount = $insert[$i]['stuNum'];
      8. }
      9. for ($j=0; $j <$tempCount ; $j++) { //开始插入
      10. if ($insert[$i]['stuNum'] != 0) { //逐一插入导师的学生信息
      11. $excel->getActiveSheet()->setCellValue('F'.($j+$oldTemp),$insert[$i]['tstudentL'][$j]['sname']);
      12. $excel->getActiveSheet()->setCellValue('G'.($j+$oldTemp),$insert[$i]['tstudentL'][$j]['snum']);
      13. $excel->getActiveSheet()->setCellValue('H'.($j+$oldTemp),$insert[$i]['tstudentL'][$j]['stele']);
      14. }
      15. $excel->getActiveSheet()->getStyle('F'.($j+$oldTemp))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
      16. $excel->getActiveSheet()->getStyle('G'.($j+$oldTemp))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
      17. $excel->getActiveSheet()->getStyle('H'.($j+$oldTemp))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
      18. }
      19. $excel->getActiveSheet()->setCellValue('A'.$oldTemp,($i+1)); //设置单元格的值
      20. $excel->getActiveSheet()->setCellValue('B'.$oldTemp,$insert[$i]['dep']);
      21. $excel->getActiveSheet()->setCellValue('C'.$oldTemp,$insert[$i]['tname']);
      22. $excel->getActiveSheet()->setCellValue('D'.$oldTemp,$insert[$i]['position']);
      23. $excel->getActiveSheet()->setCellValue('E'.$oldTemp,$insert[$i]['title']);
      24. $newTemp = $oldTemp + $tempCount;
      25. if ($insert[$i]['stuNum'] != 1 && $insert[$i]['stuNum'] != 0) {
      26. for ($k=0; $k <5 ; $k++) {
      27. $excel->getActiveSheet()->mergeCells($letter[$k].$oldTemp.':'.$letter[$k].($newTemp-1)); //根据导师的学生数合并A、B、C、D、E列的单元格
      28. }
      29. }
      30. for ($z=0; $z <5 ; $z++) {
      31. $excel->getActiveSheet()->getStyle($letter[$z].$oldTemp.':'.$letter[$z].($newTemp-1))->applyFromArray($styleArray); //设置单元格格式:水平、垂直居中、加边框
      32. }
      33. $oldTemp = $newTemp;
      34. }
  • 直接输出至浏览器,即下载至本地,只需直接加入代码就行

    1. $write = new \PHPExcel_Writer_Excel5($excel);
    2. header("Pragma: public");
    3. header("Expires: 0");
    4. header("Cache-Control:must-revalidate, post-check=0, pre-check=0");
    5. header("Content-Type:application/force-download");
    6. header("Content-Type:application/vnd.ms-execl");
    7. header("Content-Type:application/octet-stream");
    8. header("Content-Type:application/download");;
    9. header('Content-Disposition:attachment;filename='.'"'.$insert[0]['grade'].'级导师互选结果.xls"'); //可以对文件名进行处理
    10. header("Content-Transfer-Encoding:binary");
    11. $write->save('php://output');

四、实践效果动图

学生Excel导入:

Excel模版导出:

结果导出:

五、总结

  • 期间遇到了很多的bug,不断的上网找资料、找博客,学到了很多的知识,比如在一个''上刚了非常多的时间,最后找到错误的时候又喜又气的,还有在往Excel中写数据的时候,碰到一个未定义数组下标[0]的错误的时候,花了更多的时间,反反复复的检查代码愣是没发现错误在哪里,躺在床上没解决bug不甘心又下床苦寻,最后发现数据库中的数据有一些是空的,直接插入会出错,要做一些相应的处理

  • 学到了新知识心里是惊喜的,不过我也是得去做下编译实验的。。

PHPExcel使用体会的更多相关文章

  1. phpexcel读取输出操作

    //读取 <?php header("Content-Type:text/html;charset=utf-8"); include 'Classes/PHPExcel.ph ...

  2. [moka同学笔记]PHPexcel之excel导出和导入

    原案例来自http://www.sucaihuo.com/有修改 1.目录结构(文件不用解释,应该都可以看得懂,直接看代码)

  3. phpexcel导出数据表格

    1.下载phpexcel(李昌辉) 2.在页面引入phpexcel的类文件,并且造该类的对象 include("../chajian/phpexcel/Classes/PHPExcel.ph ...

  4. phpexcel 字符串转码

    问题状况:在导入excel的时候会出现 PHPExcel_RichText Object ( [_richTextElements:PHPExcel_RichText:] => PHPExcel ...

  5. thinkphp3.2和phpexcel导入

    先整个最基础的代码,理解了这个,后面的就非常简单了 $file_name= './Upload/excel/123456.xls'; import("Org.Util.PHPExcel&qu ...

  6. PHPExcel 大数据的导出

    PHPExcel 是一个php语言读取导出数据.导入生成Excel的类库,使用起来非常方便,但有时会遇到以些问题,比如导出的数据超时,内存溢出等. 下面我们来说说这些问题和解决办法. PHPExcel ...

  7. PHPExcel按单元格读取数据

    import('ORG.Util.PHPExcel.PHPExcel'); $objReader = new PHPExcel_Reader_Excel2007(); //use excel2007 ...

  8. phpexcel读取excel的xls xlsx csv格式

    我之前写过一篇PHP读取csv文件的内容 上代码index.php <?php /** * * @author XC * */ class Excel { public $currentShee ...

  9. 解决 PHPExcel 长数字串显示为科学计数

    解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. ...

随机推荐

  1. 与TCP/IP协议的初次见面(一)

    引言 最近LZ有了一点时间,于是便拿出TCP/IP的书本开始啃.开始的时候,啃起来枯燥无味,现在好不容易有点开窍,于是赶忙记录一下,生怕自己一转眼就给忘了.不过计算机系统原理就有点可惜了,最近一直没时 ...

  2. Java程序-进程中的"进程"

    进程 我们知道程序在磁盘上的时候是静态的,当他被加载到内存的时候,就变成了一个动态的,称为进程,如下图是程序被加载到内存后,在内存中的分布情况如下      此图来自http://blog.csdn. ...

  3. Android开发自学笔记(Android Studio1.3.1)—2.开始第一个Android应用

    一.前言      使用Android Studio开发Android应用是一件非常简单的事情,因为它会帮你自动完成很多工作.本篇我们主要完成一个单击按钮在文本框显示当前时间的简单应用,借此来演示一下 ...

  4. 使用Aspose.Cells生成Excel的方法详解(转)

    using System; using System.Collections.Generic;  using System.Linq;  using System.Web;  using System ...

  5. MATLAB实现频数直方图——hist的使用

      "hist" is short for "Histogram(直方图.柱状图)". 1.N = hist(Y) bins the elements of Y ...

  6. 使用ContentProvider进行应用程序间的数据交互

    什么是ContentProvider: ContentProvider用来管理数据的访问规则.它允许你的应用程序向外界暴露需要被访问的数据. 是Android的四大组件之一. ContentProvi ...

  7. AngularJS 日期转换字符串

    日期转换成字符串的办法有很多种,其中最简单的方法是 使用AngularJS的filter来实现. $filter('date')(date, 'yyyyMM'): $filter('date')(da ...

  8. SpringMVC学习--springmvc原理

    简介 springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合.springmvc是一个基于mvc的web框架. spring的结构图: mvc在b/ ...

  9. webkit webApp 开发技术要点总结

    如果你是一名前端er,又想在移动设备上开发出自己的应用,那怎么实现呢?幸好,webkit内核的浏览器能帮助我们完成这一切.接触 webkit webApp的开发已经有一段时间了,现把一些技巧分享给大家 ...

  10. 开发错误记录七: Failed to create JVM:error code -4

    今天启动Android studio 直接报如下错误: 用 java -verion 发现并不是环境变量没配置好,而是系统分配的内存,没有达到,as 的要求一种是:重启电脑,再启动 就ok 二种是 重 ...