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 相关文章推荐
[FAQ]PHP中的一些常识:类篇
Oct 09 PHP
php&amp;java(三)
Oct 09 PHP
PHPMailer安装方法及简单实例
Nov 25 PHP
PHP中使用gettext来支持多语言的方法
May 02 PHP
PHP+jQuery实现自动补全功能源码
May 15 PHP
PHP下获取上个月、下个月、本月的日期(strtotime,date)
Feb 02 PHP
PHP命令行脚本接收传入参数的三种方式
Aug 20 PHP
php实现图片转换成ASCII码的方法
Apr 03 PHP
深入浅出php socket编程
May 13 PHP
php基于Snoopy解析网页html的方法
Jul 09 PHP
PHP如何将log信息写入服务器中的log文件
Jul 29 PHP
老生常谈php中传统验证与thinkphp框架(必看篇)
Jun 10 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
Syphon 虹吸式咖啡壶冲煮–拨动法
2021/03/03 冲泡冲煮
NO3第三帝国留言簿制作过程
2006/10/09 PHP
php查询whois信息的方法
2015/06/08 PHP
php中namespace及use用法分析
2016/12/06 PHP
Yii2.0实现生成二维码功能实例
2017/10/24 PHP
PHP crc32()函数讲解
2019/02/14 PHP
javascript中length属性的探索
2011/07/31 Javascript
JavaScript执行效率与性能提升方案
2012/12/21 Javascript
利用jq让你的div居中的好方法分享
2013/11/21 Javascript
js中对象的声明方式以及数组的一些用法示例
2013/12/11 Javascript
浅谈javascript的调试
2015/01/28 Javascript
window.location.reload 刷新使用分析(去对话框)
2015/11/11 Javascript
javascript省市区三级联动下拉框菜单实例演示
2015/11/29 Javascript
AngularJS过滤器filter用法实例分析
2016/11/04 Javascript
关于js函数解释(包括内嵌,对象等)
2016/11/20 Javascript
SpringMVC+bootstrap table实例详解
2017/06/02 Javascript
详解用函数式编程对JavaScript进行断舍离
2017/09/18 Javascript
JS中双击和单击事件冲突的解决方法
2018/04/09 Javascript
vue项目移动端实现ip输入框问题
2019/03/19 Javascript
详解vue-video-player使用心得(兼容m3u8)
2019/08/23 Javascript
解决Vue + Echarts 使用markLine标线(precision精度问题)
2020/07/20 Javascript
js实现全选和全不选功能
2020/07/28 Javascript
python获取文件扩展名的方法
2015/07/06 Python
Python日期的加减等操作的示例
2017/08/15 Python
Python基于贪心算法解决背包问题示例
2017/11/27 Python
基于Django filter中用contains和icontains的区别(详解)
2017/12/12 Python
flask入门之文件上传与邮件发送示例
2018/07/18 Python
Python字典循环添加一键多值的用法实例
2019/01/20 Python
Python generator生成器和yield表达式详解
2019/08/08 Python
python 代码实现k-means聚类分析的思路(不使用现成聚类库)
2020/06/01 Python
音乐学个人的自荐书范文
2013/11/26 职场文书
2014年药店工作总结
2014/11/20 职场文书
周恩来的四个昼夜观后感
2015/06/03 职场文书
电影圆明园观后感
2015/06/03 职场文书
2016年9月份红领巾广播稿
2015/12/21 职场文书
OpenCV实现普通阈值
2021/11/17 Java/Android