tp5导出csv

前言:在列表页,根据搜索结果,导出数据;csv相对于excel的优点是数据量大,速度快;有些具体细节不多说了,自己打印调试;

1.html部分:使用一个简单的a标签,按钮也可以;
 <a href="javascript:;" onclick="export_csv()" dialog-title="导出csv" class="btn btn-primary btn-sm">导出csv</a>
2.js部分:使用了jquery
 function export_csv() {
		//获取搜索字段值,一般是selcet和input,(自行查询各个标签的获取方法)
		var param1 = $("select[name='area_1']").val();
		var param2 = $("select[name='area_2']").val();
		...
		var param6 = $("input[name='num']").val();
		var param7 = $("input[name='start_time']").val();
		var param8 = $("input[name='end_time']").val();
		//思考:有的时候搜索条件很多,不知道会不会超出get方法携带参数的大小
		url = "/admin/some_model/toCsv?param1"+param1+"&param2="+param2+...+"&param8="+param8;
		window.location.href = url;
}
3.后台处理

导出的代码要参考 列表的代码;这样就能保证导出的数据和列表的数据一样

 public function toCsv()
    {

        $start = Request::param('start','');
        $end = Request::param('end','');
        $name = Request::param('name','');

        $field = '*';
        $where = [];
        if ($start){
            $where[] = ['create_time','>=',$start . ' 00:00:00'];
        }
        if ($end){
            $where[] = ['create_time','<=',$end . ' 23:59:59'];
        }
        if ($name){
            $where[] = ['name','like','%'.$name.'%'];
        }

        $query = Model::getQuery($where,$field,$order = 'id desc');
        $head = [
            '用户名', '角色', '最后一次登录时间', '最后一次登录ip', '创建时间'
        ];

        $fileName = '管理员信息数据' . date('_YmdHis') . '.csv';

        $this->putCsv($query,$head,$fileName);
    }

	public function putCsv($query,$head,$fileName){
        //设置运行时间,单位秒
        set_time_limit(1800);
        //输出文件头
        header("Content-type: text/csv");
        header('Content-Type: application/vnd.ms-excel;charset=utf-8');
        header("Content-Disposition: attachment;filename=$fileName");
        header('Cache-Control: no-cache');
        header('Expires: 0');
        //总条数
        $total = $query->count();

        $pageSize = 10000;//每次只从数据库取10000条以防变量缓存太大
        // 每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
        $limit = 10000;
        // buffer计数器
        $cnt = 0;

        $fp = fopen('php://output', 'w');
        $key = [];
        foreach ($head as $i => $v) {
            // CSV的Excel支持GBK编码,一定要转换,否则乱码
            $head[$i] =iconv("utf-8","gb2312//IGNORE",$v);
            array_push($key, $i);
        }
        fputcsv($fp, $head);

//这里可以先写一些测试数据,尝试是否成功
//        $lists = [
//            '小李','super','123','123',123
//        ];
//        fputcsv($fp,$lists);
//        fclose($fp);
//        exit();

        for ($i = 0; $i < ceil($total/$pageSize); $i++){
            $lists = $query->limit($i*$pageSize,$pageSize)->select();

            foreach ($lists as $k => $v){
                //做一些转换
                if ($v['role_type'] == StatusCode::SUPER_ADMIN){
                    $v['role_type'] = '超级管理员';
                }elseif ($v['role_type'] === StatusCode::ORDINARY_ADMIN){
                    $v['role_type'] = '普通管理员';
                }else{
                    $v['role_type'] = '客服';
                }

                $row = [
                   $v['name'],$v['role_type'],$v['last_login_time'],$v['last_login_ip'],$v['create_time']
                ];
                //字符集转换
                foreach ($row as $key => $val) {
                    if (!empty($val)) {
                        $val=is_numeric($val) ? $val . "\t" : $val;
                        $row[$key] = iconv('utf-8', 'gb2312//IGNORE', $val);
                    }
                }

                $cnt++;
                if ($limit == $cnt){
                    //刷新一下输出buffer,防止由于数据过多造成问题
                    ob_flush();
                    flush();
                    $cnt = 0;
                }

                fputcsv($fp, $row);//写入第一行数据
            }
        }

        fclose($fp);
        exit();
    }
小tips:
  • csv格式的文件,用excel打开数字会强制转换成科学记数法;想身份证号码可以前后端约定加个字母,将其转换成字符串,取用时切割去字母即可
  • 有些偏僻汉字,无法正常显示时,编码问题:gbk的字符数量 大于gb2312,将gb2312替换成gbk
  • Cannot modify header information - headers already sent by;这个报错很有可能是字段转换时,写错字段名,特别是导出字段非常多时,需要逐个排除;建议一边调试一边写代码
  • 目前一次性全部导出过13W的多字段csv,速度还可以
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值