牛骨文教育服务平台(让学习变的简单)
博文笔记

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

创建时间:2017-09-02 投稿人: 浏览次数:523

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

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

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

下面直接上代码。


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

/**
 * [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 AppRepositoriesDataAnalysisDataAnalysisRepository;

use AppHttpControllersExcelController;

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][] = "	".$v->order_sn;
        $data[$k][] = $v->amount;
        $data[$k][] = $v->recorded;
        $data[$k][] = ($v->payment==1)?"微信支付":"其他";
        $data[$k][] = "	".$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][] = "	".$v->order_sn;

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

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。