1、表格导出
1.1准备数据:
//导出--数据准备
public function exportData(){
$post = input();
//导出订单的限制条件
if(!empty($post['s_time']) && !empty($post['e_time'])){
$a_where['UNIX_TIMESTAMP(a.order_time)'] = ['between',[strtotime($post['s_time']) ,strtotime($post['e_time'])]];
}else{
ajax_return_adv_error('请选择订单日期范围!');
}
//导出数据准备
$key_data = DB::table('tp_platform_order')->alias('a')
->field('a.u_id,a.order_id,a.order_time,b.dish,b.dish_number')
->join('tp_platform_order_item b','b.order_id=a.order_id')
->where($a_where)
->select();
//线上门店名称
$online_store_data = DB::table('tp_admin_online_store')
->field('id,u_name,u_platform')
->where('isdelete = 0')
->column('u_name,u_platform','id');
//新数组拼接数据
$arr = [];
foreach ($key_data as $key => $value) {
//因为表格直接是从1开始,第一行是表头,所以新数组的key值设置--直接从2开始
$key += 2;
$arr[$key]['u_name'] = isset($online_store_data[$value['u_id']]) ? $online_store_data[$value['u_id']]['u_name'] : '未知';
$arr[$key]['u_platform'] = isset($online_store_data[$value['u_id']]) ? $online_store_data[$value['u_id']]['u_platform'] : '未知';
$arr[$key]['u_id'] = $value['u_id'];
$arr[$key]['order_id'] = $value['order_id'];
$arr[$key]['order_time'] = $value['order_time'];
$arr[$key]['dish'] = $value['dish'];
$arr[$key]['dish_number'] = $value['dish_number'];
$arr[$key]['start'] = $key;
$arr[$key]['end'] = $key;
}
//根据order_id识别需要合并的单元格
$crr = [];
foreach($arr as $key => $value){
if(isset($crr[$value['order_id']]['order_id'])){
$arr[$crr[$value['order_id']]['key']]['end'] = $value['end'];
}else{
$crr[$value['order_id']]['key'] = $key;
$crr[$value['order_id']]['order_id'] = $value['order_id'];
$crr[$value['order_id']]['start'] = $value['start'];
$crr[$value['order_id']]['end'] = $value['end'];
}
}
return array($arr,$post['s_time'],$post['e_time']);
}
1.2表格导出
//导出
public function export(){
$post = input();
$data = $this->exportData();
$brr = $data[0];
$s_time = $data[1];
$e_time = date('Y-m-d',strtotime($data[2]));
if (empty($brr)) {
ajax_return_adv_error('没有要导出的数据');
}
Vendor('PHPExcel.PHPExcel');//调用类库,路径是基于vendor文件夹的
Vendor('PHPExcel.PHPExcel.Worksheet.Drawing');
Vendor('PHPExcel.PHPExcel.Writer.Excel2007');
$objExcel = new \PHPExcel();
//set document Property
$objWriter = \PHPExcel_IOFactory::createWriter($objExcel, 'Excel2007');
$objActSheet = $objExcel->getActiveSheet();
$key = ord("A");
//表列
$letter =explode(',',"A,B,C,D,E,F,G");
//表头
$arrHeader = array('线上门店名称','平台','线上门店ID','订单编号','下单时间','商品名称','商品数量');
//填充表头信息
$lenth = count($arrHeader);
for($i = 0;$i < $lenth;$i++) {
$objActSheet->setCellValue("$letter[$i]1","$arrHeader[$i]");
};
//设置列宽
$objActSheet->getColumnDimension('A')->setWidth(30);
$objActSheet->getColumnDimension('D')->setWidth(30);
$objActSheet->getColumnDimension('E')->setWidth(30);
$objActSheet->getColumnDimension('F')->setWidth(60);
//填充表格信息
foreach($brr as $key=> $value){
$objActSheet->setCellValue('A'.$key, $value['u_name']);
$objActSheet->setCellValue('B'.$key, $value['u_platform']);
$objActSheet->setCellValue('C'.$key, $value['u_id']);
$objActSheet->setCellValueExplicit('D'.$key, $value['order_id'], \PHPExcel_Cell_DataType::TYPE_STRING);
$objActSheet->setCellValue('E'.$key, $value['order_time']);
$objActSheet->setCellValue('F'.$key, $value['dish']);
$objActSheet->setCellValue('G'.$key, $value['dish_number']);
$num = $value['end'] - $value['start'];
//如果$num>=1,说明是需要合并的表格
if($num >= 1){
$objActSheet->mergeCells('A'.$value['start'].':'.'A'.$value['end']);
$objActSheet->mergeCells('B'.$value['start'].':'.'B'.$value['end']);
$objActSheet->mergeCells('C'.$value['start'].':'.'C'.$value['end']);
$objActSheet->mergeCells('D'.$value['start'].':'.'D'.$value['end']);
$objActSheet->mergeCells('E'.$value['start'].':'.'E'.$value['end']);
}
}
//文件名
$outfile = $s_time.'至'.$e_time."订单汇总表.xlsx";
//清除缓冲区,避免乱码
ob_end_clean();
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-Disposition:inline;filename="'.$outfile.'"');
header("Content-Transfer-Encoding: binary");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
$objWriter->save('php://output');
}
1.3最终样式
相同订单的数据会合并前几列,只有商品名称和数量是分开的
2、遇到的问题与解决方法
2.1-单元格合并:在数据中增加单元格标识start和end,如果这两个标识不相等,就把行start和行end合并。
2.2-导出的订单号会变成3.23542352+E18这种格式:是订单号过长导致的导出时自动转变为科学计数法,解决方法是:解决科学计数法
2.3-导入一张五万条数据的表格时(7.0M+),瞬间提示“找不到文件、请选择文件上传“:修改php.ini的配置,是限制了上传文件的大小,详见上一条博客。
2.4-导入表格时出现No cells exist within the specified range,说明excle的列表名超界错误,比如程序只需要A-E列的数据,你却导入了A-K列的数据,也许你的表格看起来只有A-E列有数据,其他地方空白,实际上别的列也占有存储空间,保险起见的解决方法:重新建立一表格,将A-E列的数据复制过来,注意只复制A-E列喔!然后再保存、导入,就成功了。
3、参考链接
PHPExcel 中文使用手册详解
PhpExcel中文帮助手册|PhpExcel使用方法
PHP递增/递减运算符
4、表格字符变量的算术运算,用于导出表格的列自增长
一个for循环,加上,’++$s . PHP_EOL;’,s是自定义的字符,比如A、B等,当导出表格的列依据实际情况有所变化时,可以用个来调控列。