ThinkPHP3.2关于ajax导出excel(phpexcel)

8 篇文章 0 订阅

在这个上面我已经卡了很久不知道怎么搞,主要是卡在前端上面,然后我各种百度各种群询问,可是没能解决,或许主要因为自己询问方式不对导致,别人解释的不是我想要的结果。

在今天的一个百度问题上,我找到了我想要的答案。

当你点击导出日志的按钮的时候,就会出现下载excel(这是谷歌浏览器是这样的)

火狐浏览器是这样的效果。

那么我就开始说我的功能需求:

在页面上勾选你想要导出的数据,checkbox复选框,在点击导出日志,就会导出你勾选的部分。当你什么都没选择的时候,那么就会导出数据库这张表的所有数据。

view层

以下就是js部分

function getLog(){
		var  list=$("input[name='idss[]']:checked").serialize()+'&'
              +$("input[name='ids[]']:checked").serialize();
		$.ajax({
			type: "post",
			url: "{:U('action/withLog')}",
			//traditional: true,
			data:list,
			dataType: "json",//后台处理后返回的数据格式
			async:false,
			success: function (data){
				var $a = $("<a>");
				$a.attr("href", data.file);
				$a.attr("download", data.filename);
				$("body").append($a);
				$a[0].click();
				$a.remove();
			},
			error: function (msg){
			}
		});
	}

controller层

 public function withLog($ids = 0,$idss=''){
        $map=implode(',',$ids);
    
        if(empty($ids)){
            $maps=array();
        }else{
            $maps['onethink_action_log.id']=array('in',$map);
        }

        $field=array();
        //根据idss来判断要查询哪些字段
        if(empty($idss)){
            $field[]='onethink_member.nickname';
            $field[]='onethink_action.title';
            $field[]='onethink_action_log.*';
        }else{
            if(in_array('user_id',$idss)){
                $field[]='onethink_member.nickname';
            }
            if(in_array('action_id',$idss)){
                $field[]='onethink_action.title';
            }
            foreach( $idss as $k=>$v) {
                $field[]='onethink_action_log.'.$v;
            }
        }
        //关联表查询
        $driver =  M('ActionLog')
            ->where($maps)
            ->field($field)
            ->join('LEFT JOIN __MEMBER__ ON __MEMBER__.uid=__ACTION_LOG__.user_id')
            ->join('LEFT JOIN __ACTION__ ON __ACTION__.id=__ACTION_LOG__.action_id')
            ->select();

        $flag=false;
        $arr=array();
        //获取键名,并重新组成数组,将新数组的键名换为ABCD。
        $data=array_keys($driver[0]);
        foreach ($data as $key=>$value){
            $arr[chr($key+65)]=$value;
            if('create_time'==$value){
                $flag=true;
            }
        }
        $daArr=array();
        //将时间戳转换为时间
        if($flag){
            foreach($driver as $keys=>$val){
                $val["create_time"] = date('Y-m-d H:m:s',intval($val["create_time"]));
                $daArr[$keys]=$val;
            }
        }else{
            $daArr=$driver;
        }
        //调用公共方法中的getExcel
        $res=getExcel($daArr,$arr,'日志','Excel5');
        if ($res) {
            $this->ajaxReturn($res, "json");
        }
    }

在控制层的时候,我也卡了很久,数据查询上,我一直在纠结怎么查询三张表,将其他两张表的两个字段加进去,我犹豫了很久,也问过别人,之前是想将第一张表数据查询出来,然后在利用user_id在user表中一个个查询,但是会出现几个问题,第一,查询速度太慢,第二,查询到的用户只有root,第二个问题我一直很纠结,不知道出现在什么地方。在join 的问题上,我这里已经说明 https://blog.csdn.net/jachinFang/article/details/99430047

公共方法中common

function getExcel($driver,$data,$title,$type='Excel5'){

//    var_dump($driver);exit;
    $objExcel = new \PHPExcel();

    $objWriter = \PHPExcel_IOFactory::createWriter($objExcel, $type);

    $objExcel->getActiveSheet()->getDefaultStyle()->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);

    $objExcel->getActiveSheet()->getDefaultStyle()->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);

    $objExcel->getActiveSheet()->getDefaultStyle()->getFont()->setSize(10);

    $objExcel->getActiveSheet()->getStyle('A2:D2')->getFont()->setBold(true);

    $objExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);

    $objExcel->getActiveSheet()->getRowDimension('1')->setRowHeight(30);

    $objExcel->getActiveSheet()->getRowDimension('2')->setRowHeight(20);



    $objActSheet = $objExcel->getActiveSheet(1);

    $objActSheet->setTitle($title);//设置excel的标题

    $objActSheet->setCellValue('A1',$title);
    foreach ($data as $k=>$v){
        $str=$k.'2';
        $max=$k;
        $objActSheet->setCellValue($str,$v);
    }
    $max='A1:'.$max.'1';
    $objExcel->getActiveSheet()->mergeCells($max);
    $count = count($driver);
    for ($i = 3;$i <= $count+1; $i++){
        foreach ($data as $k=>$v){
            $str=$k.$i;
            $objExcel->getActiveSheet()->setCellValue($str,$driver[$i-3][$v]);
        }


    }
    $objExcel->setActiveSheetIndex(0);


    browser_export($type,$title);//输出到浏览器
    ob_start();
    $objWriter->save("php://output");
    $xlsdata = ob_get_contents();
    ob_end_clean();
    $data=['filename' => $title.'.xls', 'file' => "data:application/vnd.ms-excel;base64," . base64_encode($xlsdata)];
    return $data;
}


function browser_export($type='Excel5',$filename){
    ob_end_clean();//清除缓冲区,避免乱码
    header("Content-Type:text/html;charset=utf-8");
    if($type==='Excel5'){
        header('Content-Type: applicationnd.ms-excel');
        header('Content-Disposition: attachment;filename="'.$filename.'.xls"');
    }else{
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="'.$filename.'.xlsx"');
    }
    header('Cache-Control: max-age=0');
}

公共方法里面最关键的几句代码可能是

    ob_start();
    $objWriter->save("php://output");
    $xlsdata = ob_get_contents();
    ob_end_clean();

我之前一直不能返回数据,所以也卡了一会。

总结一句话,遇到问题不可怕,可怕的是,你知道问题却不知道如何表达,如何去百度。我就是死在这个上面,知道问题关键,却不知道如何正确表达。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值