导读:大家都知道使用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打开它的时候就知道它不是数字列。