PHPExcel导出设置
这是我自己在项目中总结出的一套模板,主要是为了解决以下情况:
- PHPExcel操作不熟练
- 在专门的类中只关注数据,而将PHPExcel操作分离出来
当时是我第一次接触PHPExcel,对于其中的操作我是实在不想在每一个地方都引用一次PHPExcel的类,所以我就专门把PHPExcel导出在父类中,再在子类中设置数据的设置。
设置父类
<?php
abstract class Base{
/**
* 将数据保存到本地指定文件夹
* @param $excelSavePath string 文件保存路径
* @param $param array | string 传递额外参数
* @throws Exception
* @throws \PHPExcel_Exception
*/
public function outputExcel($excelSavePath,$param){
$data=$this->organizeOutputData($param);
$phpExcelInstance=new \PHPExcel();
$phpExcelInstance=$this->before($phpExcelInstance);
// 设置PHPExcel宽度
$length = 0;
if (isset($data[0][0])){
$length = count($data[0][0]);
}
for ($i = 0; $i < $length; $i++) {
$phpExcelInstance->getActiveSheet()->getColumnDimension(\PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(true);
}
foreach ($data as $sheet=>$value){
foreach ($value as $item){
foreach ($item as $position=>$v) {
$phpExcelInstance->getSheet($sheet)->setCellValue($position,$v);
}
}
}
$phpExcelInstance=$this->after($phpExcelInstance);
try{
$objWriter = \PHPExcel_IOFactory::createWriter($phpExcelInstance, 'Excel5');
$objWriter->save($excelSavePath);
}catch (\Exception $e){
throw new Exception("生成excel时出错:".$e->getMessage());
}
}
// 设置抽象方法,让子类中需要关注组件数据
abstract protected function organizeOutputData($param);
/**
* 子类可以在开始前做一些额外的操作
* @param \PHPExcel $PHPExcel
* @return \PHPExcel
*/
protected function before(\PHPExcel $PHPExcel){
return $PHPExcel;
}
/**
* 子类可以在结束操作前做一些操作
* @param \PHPExcel $PHPExcel
* @return \PHPExcel
*/
protected function after(\PHPExcel $PHPExcel){
return $PHPExcel;
}
}
简单来说就是我把PHPExcel作为最外层输出,而各自的子类,只需要实现抽象方法organizeOutputData
,将数据组建好之后返回给PHPExcel来生成Excel,并且考虑到要设置一些样式,所以设置了两个钩子函数,before
和after
来做一些额外的操作。
子类需要返回的数组规定格式如下:
$returnData=array(
$sheet=>array(
$position=>$value
)
);
// 实际值
$demo=array(
0=>array(
'A1'=>"A1这个位置的值"
)
);
设置子类
<?php
class Child extends Base{
private static $staticKey=0;
public $key=1;
protected function organizeOutputData($param){
$returnData[]=self::returnTemplate();
// 假设下面是从数据库获取数据
$dataBaseData=array();
foreach ($dataBaseData as $key=>$value){
$this->key=$key+1;
// 你可以在这里根据数据库的值,对对应的属性设置,下面都会拼接成对应的值的
$returnData[]=$this->returnData($value);
}
return [0=>$returnData];
}
protected $fundType='-';
protected $name='-';
protected $subscribe=0;
protected $fundEndDate='-';
protected $unit='-';
protected $multiple='-';
protected $invest='-';
protected $back='-';
protected $income='-';
protected $irr='-';
static protected function returnTemplate()
{
return array(
'A'.self::$staticKey=>"投资标的类别",
'B'.self::$staticKey=>"投资标的全称",
'C'.self::$staticKey=>"认缴(万元)",
// 'D'.self::$staticKey=>"投资到期日",
'D'.self::$staticKey=>"币种",
'E'.self::$staticKey=>"倍数",
'F'.self::$staticKey=>"投资(万元)",
'G'.self::$staticKey=>"回款返本(万元)",
'H'.self::$staticKey=>'回款收益-税后(万元)',
'I'.self::$staticKey=>'XIRR'
);
}
protected function returnData($param=[])
{
return array(
'A'.$this->key=>$this->fundType,
'B'.$this->key=>$this->name,
'C'.$this->key=>$this->subscribe,
// 'D'.$this->key=>$this->fundEndDate,
'D'.$this->key=>$this->unit,
'E'.$this->key=>$this->multiple,
'F'.$this->key=>$this->invest,
'G'.$this->key=>$this->back,
'H'.$this->key=>$this->income,
'I'.$this->key=>$this->irr
);
}
}
可以看到,子类只需要继承Base
,并且在其中实现organizeOutputData
,组建对应的数据即可,这里我将顶部标题和对应的内容用2个方法实现,这样的好处是如果我要改动一个值,另一个值也只需要做对应修改就可以了,比如这里就是同时将原本D
位置上的一个字段去掉了。
但是这样也有一个问题,就是修改起来不方便,因为我将A
到I
固定写死了,当然你也可以不写死,最后拼接出来就可以了,反正这里就是提供一个思路,便于你们将excel导出和数据组建分开2个类去实现。
这样当你们后期修改成其他的拓展类时,只需要修改最外面的方法,其中的数据设置全部不用改,而且所有页面都是使用这一个类的话,就只需要改动这里了,再也不用担心整个项目中phpexcel
拓展类满天飞了。