博客列表 >PhpExcel 导入导出,简化接入流程,专注于业务

PhpExcel 导入导出,简化接入流程,专注于业务

Alfred的学习笔记
Alfred的学习笔记原创
2020年01月04日 13:23:36977浏览

封装PHPExcel接入类

使用的是PHPExecl-1.8

  1. <?php
  2. /*
  3. * @Author: Alfred
  4. * @Date: 2019-12-31 17:17:44
  5. * @LastAuthor : Alfred
  6. * @LastTime : 2020-01-03 13:40:10
  7. * @Description: Excel对接
  8. */
  9. namespace Common\Utility;
  10. class ExcelAction {
  11. static protected $objExcel;
  12. public function __construct() {
  13. vendor('PHPExcel.PHPExcel');
  14. self::$objExcel = new \PHPExcel();
  15. }
  16. /**
  17. * 导出
  18. *
  19. * @param string $title
  20. * @param array $cellName ['id','name'] 或 ['cuid'=>'孩子ID','real_name'=>'孩子名字']
  21. * @param array $data [['id'=>111,'name'=>'222'],['id'=>111,'name'=>'222']]
  22. * @return string 下载文件地址
  23. */
  24. public function downloadExcel($title = '', array $cellName, array $data) {
  25. $topNumber = 2; //表头有几行占用
  26. $xlsTitle = iconv('utf-8', 'gb2312', $title); //文件名称
  27. $fileName = $title . date('_YmdHis'); //文件名称
  28. $cellKey = array(
  29. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  30. 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  31. 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM',
  32. 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ',
  33. );
  34. //处理表头标题
  35. self::$objExcel->getActiveSheet()->mergeCells('A1:' . $cellKey[count($cellName) - 1] . '1'); //合并单元格(如果要拆分单元格是需要先合并再拆分的,否则程序会报错)
  36. self::$objExcel->setActiveSheetIndex(0)->setCellValue('A1', $title);
  37. self::$objExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
  38. self::$objExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(18);
  39. self::$objExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  40. self::$objExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  41. //处理表头
  42. $index = 0;
  43. foreach ($cellName as $k => $v) {
  44. self::$objExcel->setActiveSheetIndex(0)->setCellValue($cellKey[$index] . $topNumber, $v); //设置表头数据
  45. // self::$objExcel->getActiveSheet()->freezePane($cellKey[$index] . ($topNumber + 1)); //冻结窗口
  46. self::$objExcel->getActiveSheet()->getStyle($cellKey[$index] . $topNumber)->getFont()->setBold(true); //设置是否加粗
  47. self::$objExcel->getActiveSheet()->getStyle($cellKey[$index] . $topNumber)->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); //垂直居中
  48. $index++;
  49. // if ($v[3] > 0) //大于0表示需要设置宽度
  50. // {
  51. // self::$objExcel->getActiveSheet()->getColumnDimension($cellKey[$index])->setWidth($v); //设置列宽度
  52. // }
  53. }
  54. //数据表头处理方式
  55. $dataWrite = $cellName[0] ? 1 : 0; //如果是1 直接取v1 否则取 k1
  56. //处理数据
  57. foreach ($data as $k => $v) {
  58. $cell_index = 0;
  59. foreach ($cellName as $k1 => $v1) {
  60. self::$objExcel->getActiveSheet()->setCellValue($cellKey[$cell_index] . ($k + 1 + $topNumber), $v[$dataWrite ? $v1 : $k1]);
  61. $cell_index++;
  62. }
  63. }
  64. //导出execl
  65. ob_end_clean(); //清除缓冲区,避免乱码
  66. header('pragma:public');
  67. header('Content-type:application/vnd.ms-excel;charset=utf-8;name="' . $xlsTitle . '.xls"');
  68. header("Content-Disposition:attachment;filename=$fileName.xls"); //attachment新窗口打印inline本窗口打印
  69. $objWriter = \PHPExcel_IOFactory::createWriter(self::$objExcel, 'Excel5');
  70. $objWriter->save('php://output');
  71. exit;
  72. }
  73. /**
  74. * 导入,excel 头两行作为备注或注意事项描述信息
  75. *
  76. * 第三行为数据列标题如:id,name,……
  77. *
  78. * 第四行开始为列对应的数据
  79. *
  80. * @param array $file 上传的文件form-data
  81. * @param array $checkColumn 要检测的列值 ['shop_name','create_data']
  82. * @return array 读取到的数据
  83. */
  84. public function uploadExcel($file = [], $checkColumn = []) {
  85. $file_tmp_name = $file['tmp_name'];
  86. // $fileType = \PHPExcel_IOFactory::identify($file['name']); //读取不到网络文件 只能读取到固定目录的文件
  87. $fileSuffix = explode('.', $file['name']);
  88. switch (end($fileSuffix)) {
  89. case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet
  90. case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
  91. case 'xltx': // Excel (OfficeOpenXML) Template
  92. case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded)
  93. $fileType = 'Excel2007';
  94. break;
  95. case 'xls': // Excel (BIFF) Spreadsheet
  96. case 'xlt': // Excel (BIFF) Template
  97. $fileType = 'Excel5';
  98. break;
  99. }
  100. if (empty($fileType)) {
  101. return makeinformation(550, '导入失败,请上传正确的Excel格式的文件!');
  102. }
  103. //excel初始化列
  104. $cellKey = array(
  105. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  106. 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  107. 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM',
  108. 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ',
  109. );
  110. //初始化excel版本
  111. $objReader = \PHPExcel_IOFactory::createReader($fileType);
  112. //读取excel
  113. $objPHPExcel = \PHPExcel_IOFactory::load($file_tmp_name);
  114. $sheet = $objPHPExcel->getSheet(0);
  115. $highestRow = $sheet->getHighestDataRow(); // 取得有数据的总行数
  116. $highestColumn = $sheet->getHighestDataColumn(); // 取得有数据的总列数
  117. $getColumnKeyList = []; //保存读取到的列值 后续遍历数据时使用的标识 ['A'=>'shop_name','B'=>'child_id'……]
  118. foreach ($cellKey as $v) {
  119. $value = $objPHPExcel->getActiveSheet()->getCell($v . '2')->getValue();
  120. if (empty($value)) { //如果取的列值是空 直接跳出
  121. break;
  122. }
  123. $getColumnKeyList[$v] = $value;
  124. if ($v == $highestColumn) { //读取到最后一列跳出
  125. break;
  126. }
  127. }
  128. //提取标识名称与传入限定数据进行比较 ['shop_name','shop_id'……]
  129. $getColumn = array_values($getColumnKeyList);
  130. if (array_diff($checkColumn, $getColumn) || array_diff($getColumn, $checkColumn)) { //反复比较 避免得不到差值
  131. return makeinformation(550, '获取的列值与系统不匹配,请下载最新的模版再操作!', $checkColumn);
  132. }
  133. //遍历数据
  134. $result = [];
  135. for ($i = 3; $i <= $highestRow; $i++) { //从第3行开始取数据
  136. $rowData = [];
  137. foreach ($getColumnKeyList as $k => $v) {
  138. $value = $objPHPExcel->getActiveSheet()->getCell($k . $i)->getValue(); //标识对应的值,例如:['shop_name'=>'大大的店']
  139. if ($k == 'A' && is_null($value)) { //如果取的第一列的值是空则直接跳出,需要保证第一列没有空值
  140. break;
  141. }
  142. $rowData[$v] = $value;
  143. }
  144. //避免返回空值数据
  145. $rowData && $result[] = $rowData;
  146. }
  147. return makeinformation(200, '', $result);
  148. }
  149. }

以下为公共方法

  1. <?php
  2. /**
  3. * 生成返回提示信息
  4. *
  5. * @param [type] $code
  6. * @param string $desc
  7. * @param string $data
  8. * @return void
  9. */
  10. function makeinformation($code, $desc = '', $data = '') {
  11. return array("code" => $code, 'desc' => $desc, 'data' => $data);
  12. }

文件放置位置

PHPExcel-1.8及上传模版下载地址 ↓↓↓↓↓↓ :)

附件:PHPExcel-1.8及上传模版

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议