利用PHPExcel 实现excel数据的导入导出(源码实现)
利用PHPExcel 实现excel数据的导入导出(源码实现)
在开发过程中,经常会遇到导入导出的需求,利用phpexcel类实现起来也是比较容易的,下面,我们一步一步实现
提前将phpexcel类下载,并放在扩展目录中,如图所示
一、Excel导出
导出功能,相对复杂,复杂就复杂在设置导出的excel文件的样式以及内容如何循环赋值,而且导出之后的处理结果,一般是直接在通过浏览器下载到本地,或者发送邮件,在此,以下载到本地为例,下面是源码实现
1、首先是获取待导出的数据,这一步比较简单
1 //首先获取所有待发货的订单
2 $where['status'] = 2;
3 $order_model = new OrderModel();
4 $res = $order_model
5 ->with('OGModel')
6 ->where($where)
7 ->select()->toArray();
8 if(!$res) $this->error('暂无待发货的记录');
9 //dump($res);die;
10 $count = count($res);
2、设置Excel导出文件的样式以及为每个单元格赋值,这一步是导出最重要最复杂的一步,好在我都做了注释
1 //引入Excel类
2 $objPHPExcel = new \PHPExcel();
3 // 设置excel文档的属性
4 $objPHPExcel->getProperties()->setCreator("cyf")
5 ->setLastModifiedBy("cyf Test")
6 ->setTitle("order")
7 ->setSubject("Test1")
8 ->setDescription("Test2")
9 ->setKeywords("Test3")
10 ->setCategory("Test result file");
11 //设置excel工作表名及文件名
12 $title = '待发货订单';
13 $excel_filename = '待发货订单_'.date('Ymd_His');
14 // 操作第一个工作表
15 $objPHPExcel->setActiveSheetIndex(0);
16 //第一行设置内容
17 $objPHPExcel->getActiveSheet()->setCellValue('A1',$excel_filename);
18 //合并
19 $objPHPExcel->getActiveSheet()->mergeCells('A1:AC1');
20 //设置单元格内容加粗
21 $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
22 //设置单元格内容水平居中
23 $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
24 //设置excel的表头
25 $sheet_title = array('订单编号','下单时间','订单金额','订单状态','支付方式','付款时间','支付单号','配送方式',
26 '收货人','联系电话','省','市','区','地址','运费','商品名称','商品货号','商品规格','商品数量','商品单价',
27 '发货单号','卖家备注','实付金额','微信/支付宝金额','余额支付','优惠金额','买家备注','物流公司','物流单号');
28 // 设置第一行和第一行的行高
29 $objPHPExcel->getActiveSheet()->getRowDimension('1')->setRowHeight(20);
30 $objPHPExcel->getActiveSheet()->getRowDimension('2')->setRowHeight(25);
31 $letter = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
32 'Q','R','S','T', 'U','V','W','X','Y','Z','AA','AB','AC');
33 //设置单元格
34 $objPHPExcel->getActiveSheet()->getStyle('A2:AC2')->getBorders()->getAllBorders()->setBorderStyle(\PHPExcel_Style_Border::BORDER_THIN);
35 //首先是赋值表头
36 for ($k=0;$k<29;$k++) {
37 $objPHPExcel->getActiveSheet()->setCellValue($letter[$k].'2',$sheet_title[$k]);
38 $objPHPExcel->getActiveSheet()->getStyle($letter[$k].'2')->getFont()->setSize(10)->setBold(true);
39 //设置单元格内容水平居中
40 $objPHPExcel->getActiveSheet()->getStyle($letter[$k].'2')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
41 //设置每一列的宽度
42 $objPHPExcel->getActiveSheet()->getColumnDimension($letter[$k])->setWidth(18);
43 $objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(30);
44
45 }
46 //开始赋值
47 for ($i=0;$i<$count;$i++) {
48 //先确定行
49 $row = $i+3;//再确定列,最顶部占一行,表头占用一行,所以加3
50 $temp = $res[$i];
51 for ($j = 0;$j<29;$j++) {
52 //开始为每个单元格赋值
53 //初始化地址数据
54 $address_arr = [];
55 $address_arr = explode(',',$temp['address_address']);
56 //初始化商品数据
57 $product_name = $product_number = $product_attr = $product_num = $product_price = '';
58 $cl = ','.chr(10);
59 foreach ($temp['o_g_model'] as $v) {
60 $product_name .= $v['title'].$cl;
61 $product_number .= $v['attrid'].$cl;
62 $attr = [];
63 $attr = json_decode($v['attr_name'],true);
64 if ($attr) {
65 foreach ($attr as $vv) {
66 $product_attr .= $vv.' ';
67 }
68 $product_attr .= $cl;
69 }
70 $product_num .= $v['num'].$cl;
71 $product_price .= $v['user_price'].$cl;
72 }
73 switch ($j) {
74 case 0 :
75 //订单编号
76 $cellvalue = $temp['order_num'];
77 break;
78 case 1 :
79 //下单时间
80 $cellvalue = date('Y-m-d H:i:s',$temp['addtime']);
81 break;
82 case 2 :
83 //订单金额
84 $cellvalue = $temp['price_sum'];
85 break;
86 case 3 :
87 //订单状态
88 $cellvalue = lang('ORDER_STATUS')[$temp['status']];
89 break;
90 case 4 :
91 //支付方式
92 $cellvalue = lang('ORDER_PAY')[$temp['pay_type']];
93 break;
94 case 5 :
95 //付款时间
96 $cellvalue = '';
97 break;
98 case 6 :
99 //支付单号
100 $cellvalue = '';
101 break;
102 case 7 :
103 //配送方式
104 $cellvalue = lang('POST_TYPE')[$temp['post_type']];
105 break;
106 case 8 :
107 //收货人姓名
108 $cellvalue = $temp['address_name'];
109 break;
110 case 9 :
111 //联系电话
112 $cellvalue = $temp['address_phone'];
113 break;
114 case 10 :
115 //省
116 $cellvalue = $address_arr[0];
117 break;
118 case 11 :
119 //市
120 $cellvalue = $address_arr[1];
121 break;
122 case 12 :
123 //区
124 $cellvalue = $address_arr[2];
125 break;
126 case 13 :
127 //地址
128 $cellvalue = $address_arr[3];
129 break;
130 case 14 :
131 //运费
132 $cellvalue = $temp['p_price'];
133 break;
134 case 15 :
135 //商品名称
136 $cellvalue = $product_name;
137 break;
138 case 16 :
139 //商品货号
140 $cellvalue = $product_number;
141 break;
142 case 17 :
143 //商品规格
144 $cellvalue = $product_attr;
145 break;
146 case 18 :
147 //商品数量
148 $cellvalue = $product_num;
149 break;
150 case 19 :
151 //商品单价
152 $cellvalue = $product_price;
153 break;
154 case 20 :
155 //发货单号
156 $cellvalue = '已废弃';
157 break;
158 case 21 :
159 //卖家备注
160 $cellvalue = '';
161 break;
162 case 22 :
163 //实付金额
164 $cellvalue = $temp['pay_money'];
165 break;
166 case 23 :
167 //微信支付宝金额
168 $cellvalue = $temp['pay_money'];
169 break;
170 case 24 :
171 //余额支付
172 $cellvalue = $temp['static_money'];
173 break;
174 case 25 :
175 //优惠金额
176 $cellvalue = $temp['coupon'];
177 break;
178 case 26 :
179 //买家备注
180 $cellvalue = '';
181 break;
182 case 27 :
183 //物流公司
184 $cellvalue = '';
185 break;
186 case 28 :
187 //物流单号
188 $cellvalue = '';
189 break;
190 }
191 //赋值
192 $objPHPExcel->getActiveSheet()->setCellValue($letter[$j].$row, $cellvalue);
193 //设置字体大小
194 $objPHPExcel->getActiveSheet()->getStyle($letter[$j].$row)->getFont()->setSize(10);
195 //设置单元格内容水平居中
196 $objPHPExcel->getActiveSheet()->getStyle($letter[$j].$row)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
197 //设置自动换行
198 if ((in_array($j,[15,16,17,18,19])) && "" != $cellvalue) {
199 $objPHPExcel->getActiveSheet()->getStyle($letter[$j].$row)->getAlignment()->setWrapText(true); // 自动换行
200 $objPHPExcel->getActiveSheet()->getStyle($letter[$j].$row)->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); // 垂直方向上中间居中
201 }
202 }
203 // 设置行高
204 $objPHPExcel->getActiveSheet()->getRowDimension($row)->setRowHeight(21);
205 }
206 unset($res);
3、设置完之后,将生成的excel文件,通过浏览器下载到本地
1 //赋值结束,开始输出
2 $objPHPExcel->getActiveSheet()->setTitle($title);
3 header('Content-Type: application/vnd.ms-excel');
4 header('Content-Disposition: attachment;filename="'.$excel_filename.'.xls"');
5 header('Cache-Control: max-age=0');
6 $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
7 $objWriter->save('php://output');
4、也可以在服务器上生成excel文件,然后发送到用户邮箱
1 $filename = __ROOT__.'/upload/files/'.$excel_filename;
2 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
3 $objWriter->save($filename);
二、Excel导入
相比导出,导入就简单多了,废话不多说,直接上源码
1、利用form表单获取上传的excel文件
1 $file = $_FILES['file'];
2 if ($file['error'] == 4) $this->error('请选择上传excel文件');
3 $file_types = explode ( ".", $file['name'] );
4 $excel_type = array('xls','csv','xlsx');
5 if (!in_array(strtolower(end($file_types)),$excel_type)){
6 $this->error("不是Excel文件,请重新上传");
7 }
2、然后,读取excel文件里面的数据,这里是边读取边处理,或者全部读取出来再处理
1 //设置获取excel对象
2 $objReader = \PHPExcel_IOFactory::createReader('Excel5');//配置成2003版本,因为office版本可以向下兼容
3 $objPHPExcel = $objReader->load($file['tmp_name'],$encode='utf-8');//$file 为解读的excel文件
4 //dump($objPHPExcel);die;
5 $sheet = $objPHPExcel->getSheet(0);
6 $highestRow = $sheet->getHighestRow(); // 取得总行数
7 $success_item = $fail_item = 0;
8 //发货
9 $order_model = new OrderModel();
10 //开始读取数据
11 for($j=3;$j<=$highestRow;$j++)
12 {
13 $order_num = $objPHPExcel->getActiveSheet()->getCell('A'.$j)->getValue();
14 $poster = $objPHPExcel->getActiveSheet()->getCell("AB".$j)->getValue();//物流公司
15 $logistics = $objPHPExcel->getActiveSheet()->getCell("AC".$j)->getValue();//物流单号
16 $comm = $objPHPExcel->getActiveSheet()->getCell("V".$j)->getValue();//卖家备注
17 //判断条件
18 if(!is_null($order_num) && $order_num){
19 $res = $order_model->where('order_num',$order_num)->field('itemid,status')->find();
20 if ($res && $res['status'] == 2) {
21 if ((!is_null($poster) && $poster) || (!is_null($logistics) && $logistics)) {
22 //更改状态
23 OrderPlanModel::addLog($res['itemid'],'确认发货',$comm);
24 $order_model->Update([
25 'status'=>3,
26 'poster'=>$poster,
27 'logistics'=>$logistics,
28 ],['itemid'=>$res['itemid']]);
29 $success_item ++;
30 } else {
31 $fail_item ++;
32 }
33 } else {
34 $fail_item ++;
35 }
36 } else {
37 $fail_item++;
38 }
39 }
40 $this->success('成功条数:'.$success_item.',失败条数:'.$fail_item);
多学、
多记、
多练、