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 相关文章推荐
解决dede生成静态页和动态页转换的一些问题,及火车采集入库生成动态的办法
Mar 29 PHP
PHP编码规范之注释和文件结构说明
Jul 09 PHP
PHP APC配置文件2套和参数详解
Jun 11 PHP
Thinkphp的volist标签嵌套循环使用教程
Jul 08 PHP
php.ini save_handler 修改不生效的解决办法
Jul 22 PHP
THINKPHP内容分页代码分享
Jan 14 PHP
如何批量清理系统临时文件(语言:C#、 C/C++、 php 、python 、java )
Feb 01 PHP
PHP之图片上传类实例代码(加了缩略图)
Jun 30 PHP
php自定义函数实现二维数组按指定key排序的方法
Sep 29 PHP
Zend Framework框架中实现Ajax的方法示例
Jun 27 PHP
php日志函数error_log用法实例分析
Sep 23 PHP
关于php开启错误提示的总结
Sep 24 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
php对二维数组按指定键值key排序示例代码
2013/11/26 PHP
php微信公众号开发之关键词回复
2018/10/20 PHP
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
js格式化金额可选是否带千分位以及保留精度
2014/01/28 Javascript
createTextRange()的使用示例含文本框选中部分文字内容
2014/02/24 Javascript
Javascript仿PHP $_GET获取URL中的参数
2014/05/12 Javascript
node.js中的fs.ftruncate方法使用说明
2014/12/15 Javascript
js实现鼠标滚轮控制图片缩放效果的方法
2015/02/20 Javascript
js实现在网页上简单显示时间的方法
2015/03/02 Javascript
原生javascript实现分页效果
2017/04/21 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
jQuery滚动插件scrollable.js用法分析
2017/05/25 jQuery
js学使用setTimeout实现轮循动画
2017/07/17 Javascript
JS轮播图实现简单代码
2021/02/19 Javascript
详解a++和++a的区别
2017/08/30 Javascript
详解vue通过NGINX部署在子目录或者二级目录实践
2018/09/03 Javascript
Bootbox将后台JSON数据填充Form表单的实例代码
2018/09/10 Javascript
element上传组件循环引用及简单时间倒计时的实现
2018/10/01 Javascript
vue实例的选项总结
2020/06/09 Javascript
[04:10]2016国际邀请赛中国区预选赛第二日TOP10精彩集锦
2016/06/28 DOTA
Python实现保证只能运行一个脚本实例
2015/06/24 Python
利用python程序生成word和PDF文档的方法
2017/02/14 Python
python下读取公私钥做加解密实例详解
2017/03/29 Python
python中模块查找的原理与方法详解
2017/08/11 Python
python单线程下实现多个socket并发过程详解
2019/07/27 Python
深入学习python多线程与GIL
2019/08/26 Python
将python字符串转化成长表达式的函数eval实例
2020/05/11 Python
关于Keras Dense层整理
2020/05/21 Python
keras的siamese(孪生网络)实现案例
2020/06/12 Python
详解Python中的编码问题(encoding与decode、str与bytes)
2020/09/30 Python
FLIR美国官网:热成像, 夜视和红外摄像系统
2018/07/13 全球购物
有限责任公司股东合作协议书
2014/12/02 职场文书
通过shell脚本对mysql的增删改查及my.cnf的配置
2021/07/07 MySQL
Java日常练习题,每天进步一点点(38)
2021/07/26 Java/Android
python标准库ElementTree处理xml
2022/05/20 Python
TS 类型兼容教程示例详解
2022/09/23 Javascript