Laravel导出大量数据到表格csv及长数字显示不全问题

导读:大家都知道使用PHPExcel类库或者Laravel Excel 都可以实现 Excel/CSV 文件导入导出功能,但是在实际开发中,实现是一回事,真正应用又是一回事。

上面提到的那两种方式都不适用于1W以上的数据量导出,速度相当慢,甚至很可能由于内存及超时的原因无法实现导出,但是线上实际需求如订单导出等,随便数量都可能达到1w,甚至百w、千w条。

那么,这个时候,我们要实现10w条甚至更大的数据量时,我们就得自己封装方法。

下面直接上代码。


封装好的导出方法
在此控制器中,App\Http\Controllers\ExcelController
你也可以封装到函数库里,此处我偷懒了

/**
 * [export 在本地导出csv数据]
 * @param  [type] $cell  [表格字段]
 * @param  [type] $title [文件名]
 * @param  [type] $data  [数据]
 * @return [type]        [description]
 */
public function localexport($cell,$title,$data){
    set_time_limit(0);
    ini_set('memory_limit', '128M');
    header('Content-Type: application/vnd.ms-execl');
    header('Content-Disposition: attachment;filename="'.$title . '.csv"');

    //以写入追加的方式打开
    $fp = fopen('php://output', 'a');

    foreach($cell as $key => $item) {
        $celldata[$key] = iconv('UTF-8', 'GBK//IGNORE', $item);
    }
    //将标题写到标准输出中
    fputcsv($fp, $celldata);
    foreach($data as $row){
    foreach($row as $key => $item) {
    //这里必须转码,不然会乱码
    $row[$key] = iconv('UTF-8', 'GBK//IGNORE', $item);
    }
    fputcsv($fp, $row);
    }
    $res = ['file'=>$title];
    return response()->json($res);
}

以下是调用导出方法的类内容
此处主要是为了能引入导出方法(localexport)及获取要导出数据的方法(excelFixeddayWxCharge)

1.命名空间

use App\Repositories\DataAnalysis\DataAnalysisRepository;

use App\Http\Controllers\ExcelController;

2.构造方法

protected $DataAnalysis;
protected $excel;

public function __construct(DataAnalysisRepository $DataAnalysis,ExcelController $excel) {
    $this->DataAnalysis = $DataAnalysis;
    $this->excel = $excel;
}

3.调用导出方法的控制器方法

public function(Request $request){
    //防止数据量大内存不够
    ini_set('memory_limit', '256M');
    //自定义表格字段
    $cell=['消费标识','订单编号','付款金额','入账金额','支付方式','微信支付订单号','优惠金额','商户标识','设备号','状态','消费时间'];
    $res = array();
    $month = $request->input('month','2017-08-01');
    //自定义导出文件名
    $title = $request->input('title','8月微信支付充值订单流水明细');
    //此方法为导出数据来源,在库文件里,你可根据自己需要的数据查数据库
    $res = $DataAnalysis->excelFixeddayWxCharge($month);

    $data=[];
    foreach($res as $k => $v){
        $data[$k][] = $v->id;
        //@1此处划重点,在下面进行说明
        $data[$k][] = "\t".$v->order_sn;
        $data[$k][] = $v->amount;
        $data[$k][] = $v->recorded;
        $data[$k][] = ($v->payment==1)?'微信支付':'其他';
        $data[$k][] = "\t".$v->payment_sn;
        $data[$k][] = $v->discount_amount;
        $data[$k][] = $v->userid;
        $data[$k][] = $v->mac_id;
        $data[$k][] = ($v->status==0)?'支付成功':'';
        $data[$k][] = $v->created_at;
    }

    $title = $title.date('YmdHis');
    $res = $excel->localexport($cell,$title,$data);//导出表格

});

注:上文划重点@1处解决长数字显示不全问题

$data[$k][] = "\t".$v->order_sn;

此处为订单号,一般订单号都是很长一串数字组成,如0157339980453950,以0开头也比较常见,那么要导出这么一长串数字到csv文件里,本身是以字串形式导出的,但是使用excel表格打开时会自动转为科学计数法,我们知道excel表格在前面拼接个英文引号 ’ 就可以,但在csv是行不通的,这时候我们只需要在前面拼接 ‘\t’即可,当excel打开它的时候就知道它不是数字列。

你可能感兴趣的:(PHP,问题(已解决),Laravel)