php中通用的excel导出方法实例


Posted in PHP onDecember 30, 2017

一.普遍导出方法

excel导出的方法网上有很多,在crm或是oa系统中导出excel是常有的事,做过的此功能人都知道,其主要操作其实是循环数据列表,然后一格一格地添加数据到固定的单元格中。只要做好了一次,其后只要复制相关代码修改修改,其他地方导出功能也就完成了。

但是这样会有两个问题:

     1.当列表数据字段修改时,需要修改大量的代码,维护艰难,改着难受;

     2.多次出现导出功能时,需要在多个地方复制大量的重复冗余代码,看着难受;

因此,有必要统一一个导出excel的方法,使用时,只需要传入数据的表头,表头字段名,数据列表,以及数据表名称,就能导出excel了。

二.使用通用的导出方法

如下图所示,只要传入4个参数,就能完成导出,使用和维护就变得简单多了。

php中通用的excel导出方法实例

好的,目标已经明确了,接下来就是代码实现了。

显然,要实现此功能,最大的一个难题是,根据单条数据的索引和表头字段次序,自动计算出每条数据中的每个字段在excel中的坐标值(如A1,B3)。

那么我们就来分析下excel的单元格坐标吧,从A1开始,纵向递增数字的值,横向递增字母,当横向字母变为Z后,下一个字母为AA,然后AB,...,ZZ,...,AAA...

这样的话,我们就知道了,纵向坐标简单,根据每条数据的索引值就可以计算得出,难的是横向坐标,该怎么计算?再仔细分析下横向坐标,可以发现是一种类似26进制的字母数字,A如果看作0,那Z表示25。但是这种数字与我们常见的16进制,8进制等又不太一样,因为当Z进位的时候,下一个数不是BA,而是AA。常见的进制中,如十进制9进位,变成10,而不是00;16进制0xF进位,变为0x10,而不是0x00。

因此可以参考进制转换的算法,然后变化一下,得出计算excel的横向坐标的方法(10进制转伪26进制):

//AAA转换
public static function toAAA($dec)
{
 if ($dec < 0) return '';
 $y = $dec % 26;
 $x = floor($dec / 26);
 return self::toAAA($x - 1) . chr($y + 65);
}

最后,附上完整代码

框架为Yii2,excel导出组件为moonlandsoft/yii2-phpexcel;

其他类似

//导出xls
public static function exportXls($array)
{
 set_time_limit(0);
 include(Url::to('@vendor/moonland/phpexcel/PHPExcel.php'));
 include(Url::to('@vendor/moonland/phpexcel/PHPExcel/Writer/Excel2007.php'));
 $titles = $array['titles'];
 $fields = $array['fields'];
 $list = $array['list'];
 $name = $array['name'];
 $count = count($titles);
 $keys = [];//A=>chr(65)
 foreach ($titles as $k => $v) {
 $keys[] = self::toAAA($k);
 }
 $objPHPExcel = new \PHPExcel();
 $objWriter = new \PHPExcel_Writer_Excel2007($objPHPExcel);
 $objPHPExcel->setActiveSheetIndex(0);
 $activeSheet = $objPHPExcel->getActiveSheet();
 $activeSheet->setTitle($name);
 $activeSheet->getStyle("A1:{$keys[$count-1]}1")->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
 $activeSheet->mergeCells("A1:{$keys[$count-1]}1");
 $activeSheet->setCellValue('A1', $name);
 //设置title,样式
 foreach ($titles as $key => $title) {
 $activeSheet->setCellValue($keys[$key] . '2', $title);
 $activeSheet->getColumnDimension($keys[$key])->setWidth(20);
 $activeSheet->getRowDimension(($key + 1))->setRowHeight(18);
 }
 $i = 3;
 foreach ($list as &$item) {
 foreach ($keys as $k => $v) {
  $val = isset($item[$fields[$k]]) ? $item[$fields[$k]] . ' ' : ' ';
  $activeSheet->setCellValue($v . $i, $val);
 }
 $i++;
 }
 $fileName = $name . "_" . date('Y_m_d_His') . '.xlsx';
 header("Cache-Control: public");
 header("Pragma: public");
 header("Content-type:application/vnd.ms-excel");
 header("Content-Disposition:attachment;filename=" . iconv("utf-8", "GB2312//TRANSLIT", $fileName));
 header('Content-Type:APPLICATION/OCTET-STREAM');
 ob_clean();
 ob_start();
 $objWriter->save('php://output');
 ob_end_flush();
}
//AAA转换
public static function toAAA($dec)
{
 if ($dec < 0) return '';
 $y = $dec % 26;
 $x = floor($dec / 26);
 return self::toAAA($x - 1) . chr($y + 65);
}

三.导出结果示例

导出结果:

php中通用的excel导出方法实例

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
在同一窗体中使用PHP来处理多个提交任务
May 08 PHP
PHP 危险函数解释 分析
Apr 22 PHP
两个强悍的php 图像处理类1
Jun 15 PHP
计算一段日期内的周末天数的php代码(星期六,星期日总和)
Nov 12 PHP
php smarty函数扩展
Mar 15 PHP
php小偷相关截取函数备忘
Nov 28 PHP
完善CodeIgniter在IDE中代码提示功能的方法
Jul 19 PHP
PHP针对多用户实现更换头像功能
Sep 04 PHP
老生常谈php 正则中的i,m,s,x,e分别表示什么
Mar 02 PHP
php面向对象之反射功能与用法分析
Mar 29 PHP
PHP编程计算两个时间段是否有交集的实现方法(不算边界重叠)
May 30 PHP
yii框架结合charjs实现统计30天数据的方法
Apr 04 PHP
利用Laravel生成Gravatar头像地址的优雅方法
Dec 30 #PHP
PHP如何实现订单的延时处理详解
Dec 30 #PHP
PHP 的Opcache加速的使用方法
Dec 29 #PHP
PHP自定义序列化接口Serializable用法分析
Dec 29 #PHP
PHP检测接口Traversable用法详解
Dec 29 #PHP
PHP聚合式迭代器接口IteratorAggregate用法分析
Dec 28 #PHP
PHP迭代器接口Iterator用法分析
Dec 28 #PHP
You might like
Protoss兵种对照表
2020/03/14 星际争霸
ThinkPHP3.1基础知识快速入门
2014/06/19 PHP
关于Laravel Route重定向的一个注意点
2017/01/16 PHP
php事务回滚简单实现方法示例
2017/03/28 PHP
Yii2配置Nginx伪静态的方法
2017/05/05 PHP
在laravel中实现将查询的对象转换为多维数组的函数
2019/10/21 PHP
Laravel框架实现抢红包功能示例
2019/10/31 PHP
如何在Laravel5.8中正确地应用Repository设计模式
2019/11/26 PHP
Kibo 用于处理键盘事件的Javascript工具库
2011/10/28 Javascript
jquery事件机制扩展插件 jquery鼠标右键事件。
2011/12/26 Javascript
jQuery Deferred和Promise创建响应式应用程序详细介绍
2013/03/05 Javascript
jquery实现导航固定顶部的效果仿蘑菇街
2014/10/22 Javascript
js 操作符汇总
2014/11/08 Javascript
IE及IE6浏览器中判断JS文件加载成功失败的方法
2015/02/18 Javascript
Javascript实现字数统计
2015/07/03 Javascript
js window对象属性和方法相关资料整理
2015/11/11 Javascript
微信小程序自定义组件
2017/08/16 Javascript
json对象及数组键值的深度大小写转换问题详解
2018/03/30 Javascript
微信小程序使用map组件实现路线规划功能示例
2019/01/22 Javascript
vue + el-form 实现的多层循环表单验证
2020/11/25 Vue.js
[01:02:32]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第二场 2月26日
2021/03/11 DOTA
python通过正则查找微博@(at)用户的方法
2015/03/13 Python
Python实现计算文件夹下.h和.cpp文件的总行数
2015/04/23 Python
Python利用带权重随机数解决抽奖和游戏爆装备问题
2016/06/16 Python
Python随机生成手机号、数字的方法详解
2017/07/21 Python
解决Pandas的DataFrame输出截断和省略的问题
2019/02/08 Python
Python给图像添加噪声具体操作
2019/03/03 Python
Python二叉树的镜像转换实现方法示例
2019/03/06 Python
python中matplotlib条件背景颜色的实现
2019/09/02 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
韩国家庭购物网上商店:Nsmall
2017/05/07 全球购物
生物技术专业研究生自荐信
2013/09/22 职场文书
艾滋病宣传活动总结
2014/05/08 职场文书
信访工作汇报材料
2014/10/27 职场文书
教师个人考察材料
2014/12/16 职场文书
mysql函数之截取字符串的实现
2022/08/14 MySQL