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 相关文章推荐
PHP5/ZendEngine2的改进
Oct 09 PHP
php MYSQL 数据备份类
Jun 19 PHP
PHP 数组遍历顺序理解
Sep 09 PHP
在PHP中检查PHP文件是否有语法错误的方法
Dec 23 PHP
PHP详解ASCII码对照表与字符转换
Dec 05 PHP
114啦源码(114la)不能生成地方房产和地方报刊问题4级页面0字节的解决方法
Jan 12 PHP
php 解决旧系统 查出所有数据分页的类
Aug 27 PHP
利用curl 多线程 模拟 并发的详解
Jun 14 PHP
php脚本守护进程原理与实现方法详解
Jul 20 PHP
详解PHP中的外观模式facade pattern
Feb 05 PHP
详解PHP队列的实现
Mar 14 PHP
laravel中数据显示方法(默认值和下拉option默认选中)
Oct 11 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一些公用函数的集合
2008/03/27 PHP
php中用socket模拟http中post或者get提交数据的示例代码
2013/08/08 PHP
php实现mysql事务处理的方法
2014/12/25 PHP
PHP连接MYSQL数据库实例代码
2016/01/20 PHP
CodeIgniter基于Email类发邮件的方法
2016/03/29 PHP
jquery(live)中File input的change方法只起一次作用的解决办法
2011/10/21 Javascript
JQuery右键菜单插件ContextMenu使用指南
2014/12/19 Javascript
调试JavaScript中正则表达式中遇到的问题
2015/01/27 Javascript
javascript的变量、传值、传址、参数之间关系
2015/07/26 Javascript
详解原生JavaScript实现jQuery中AJAX处理的方法
2016/05/10 Javascript
JS提示:Uncaught SyntaxError: Unexpected token ILLEGAL错误的解决方法
2016/08/19 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
2018/08/24 Javascript
WebGL three.js学习笔记之阴影与实现物体的动画效果
2019/04/25 Javascript
js纯前端实现腾讯cos文件上传功能的示例代码
2019/05/14 Javascript
Javascript幻灯片播放功能实现过程解析
2020/05/07 Javascript
ES6字符串的扩展实例
2020/12/21 Javascript
python套接字流重定向实例汇总
2016/03/03 Python
机器学习10大经典算法详解
2017/12/07 Python
Python获取本机所有网卡ip,掩码和广播地址实例代码
2018/01/22 Python
python实现超简单的视频对象提取功能
2018/06/04 Python
详解django2中关于时间处理策略
2019/03/06 Python
python时间序列按频率生成日期的方法
2019/05/14 Python
Python中的引用知识点总结
2019/05/20 Python
pandas.read_csv参数详解(小结)
2019/06/21 Python
Python制作数据预测集成工具(值得收藏)
2020/08/21 Python
台湾租车首选品牌:IWS艾维士租车
2019/05/03 全球购物
Johnson Fitness澳大利亚:高级健身器材
2021/03/16 全球购物
人力资源部经理的岗位职责
2014/03/04 职场文书
企业道德讲堂实施方案
2014/03/19 职场文书
创建文明城市标语
2014/06/16 职场文书
信仰心得体会
2014/09/05 职场文书
大学生个人总结范文
2015/02/15 职场文书
经理聘任证明
2015/03/02 职场文书
2015年业务工作总结范文
2015/04/10 职场文书
JavaScript选择器函数querySelector和querySelectorAll
2021/11/27 Javascript
使用 Docker Compose 构建复杂的多容器App
2022/04/30 Servers