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文件上传实例详解!!!
Jan 02 PHP
PHP采集利器 Snoopy 试用心得
Jul 03 PHP
防止本地用户用fsockopen DDOS攻击对策
Nov 02 PHP
php中$_REQUEST、$_POST、$_GET的区别和联系小结
Nov 23 PHP
CentOS 6.2使用yum安装LAMP以及phpMyadmin详解
Jun 17 PHP
php curl_init函数用法
Jan 31 PHP
php获取bing每日壁纸示例分享
Feb 25 PHP
php初始化对象和析构函数的简单实例
Mar 11 PHP
php解析字符串里所有URL地址的方法
Apr 03 PHP
PHP比较运算符的详细介绍
Sep 29 PHP
php判断当前操作系统类型
Oct 28 PHP
thinkPHP5框架实现基于ajax的分页功能示例
Jun 12 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
yii实现级联下拉菜单的方法
2014/07/31 PHP
php天翼开放平台短信发送接口实现方法
2014/12/22 PHP
php中删除、清空session的方式总结
2015/10/09 PHP
PHP中常用的数组操作方法笔记整理
2016/05/16 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
Javascript的闭包
2009/12/31 Javascript
基于jquery的让textarea自适应高度的插件
2010/08/03 Javascript
理解Javascript_13_执行模型详解
2010/10/20 Javascript
javascript去掉前后空格的实例
2013/11/07 Javascript
JavaScript设计模式之观察者模式(发布者-订阅者模式)
2014/09/24 Javascript
jquery实现submit提交表单
2015/02/03 Javascript
JavaScript小技巧整理篇(非常全)
2016/01/26 Javascript
jQuery序列化表单成对象的简单实现
2016/11/29 Javascript
JS实现字符串转驼峰格式的方法
2016/12/16 Javascript
React入门教程之Hello World以及环境搭建详解
2017/07/11 Javascript
canvas基础绘制-绚丽倒计时的实例
2017/09/17 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
2017/11/29 Javascript
对angularJs中ng-style动态改变样式的实例讲解
2018/09/30 Javascript
如何优雅地在vue中添加权限控制示例详解
2019/03/07 Javascript
在vue-cli 3中给stylus、sass样式传入共享的全局变量
2019/08/12 Javascript
OpenLayers3实现鼠标移动显示坐标
2020/09/25 Javascript
Python简单生成随机数的方法示例
2018/03/31 Python
python 实现交换两个列表元素的位置示例
2019/06/26 Python
django框架实现模板中获取request 的各种信息示例
2019/07/01 Python
django获取from表单multiple-select的value和id的方法
2019/07/19 Python
python pyinstaller打包exe报错的解决方法
2019/11/02 Python
win10系统下python3安装及pip换源和使用教程
2020/01/06 Python
python多维数组分位数的求取方式
2020/03/03 Python
pyspark 随机森林的实现
2020/04/24 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
2020/05/25 Python
阿迪达斯芬兰官方网站:adidas芬兰
2017/01/30 全球购物
《与象共舞》教学反思
2014/02/24 职场文书
保密承诺书
2014/03/27 职场文书
义卖募捐活动总结
2015/05/09 职场文书
干货:我将这样书写我的演讲稿!
2019/05/09 职场文书
常用的文件对应的MIME类型汇总
2022/04/26 HTML / CSS