PHPExecl导出大量数据卡顿问题解决(Laravel实现)
2021-01-21 06:14
标签:isa imp 推荐 exists 名称 url phpexecl time ram PHPExecl导出数据遇到复杂查询+几万条数据的情况浏览器就容易卡死,下面分享一下解决思路和过程: 先说解决思路: 1、优化查询、数据分批写入文件 2、先将表格下载到服务器,浏览器轮询服务器,表格生成完成再下载 3、表格使用队列导出 上代码 浏览器端: 1、点击导出按钮,请求exportUser接口,将文件加入队列,返回唯一key 2、使用key轮询请求getURL接口,文件生成成功则返回文件路径 3、下载文件 服务器端: 1、exportUser接口 2、生成队列任务 3、分批导出,其中getExportList方法取数据,newExportList渲染数据并导出 4、getExportList方法,取数据 5、newExportList 渲染数据方法 6、exportExcelForURL 导出表格方法 7、获取下载链接 8、开启队列(推荐配置Supervisor) PHPExecl导出大量数据卡顿问题解决(Laravel实现) 标签:isa imp 推荐 exists 名称 url phpexecl time ram 原文地址:https://www.cnblogs.com/lamp01/p/13204470.html 1
/**
* 导出列表
*/
public function exportUser(Request $request)
{
$query = $request->all();
$str=str_random(10).time();
Redis::set($str,‘‘);
$arr=[
‘query‘=>$query,
‘type‘=>1,
‘key‘=>$str
];
$this->dispatch(new exportList($arr));
return success($str);
} php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Services\UserService;
use Illuminate\Support\Facades\Log;
class exportList implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $data;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Execute the job. 处理列队数据
*
* @return void
*/
public function handle(UserService,$userService)
{
if($this->data[‘type‘]==1){ //用户导出
$userService->exportUser($this->data[‘key‘],$this->data[‘query‘]);
} elseif($this->data[‘type‘]==2){ //订单导出 xxxxxx
}
}
} /**
* 批量导出
*
* @param [type] $key
* @param [type] $query
* @return void
*/
public function exportUser($key,$query)
{
$i = 0;
$file_name = rand(1000, 9999);
while (true) {
$list = $this->getExportList($query, $i); //分页取数据
if(is_null($list)){
$list=[];
}
$res=$this->newExportList($key,$list, $file_name, ($i * env(‘EXPORT_NUM‘)) + 1);
if (count($list) )) {
return $res;
}
$i += 1;
}
}
/**
* 获取导出的数据
* @param $params
* @return mixed
*/
public function getExportList($query, $page)
{
$list = $this->UserRepositories->getListAll($query, $page);
if (!$list->isEmpty()) {
$list = $list->toArray();
$data = [];
foreach ($list as $key => $value) {
$data[$key][‘A‘] = $value[‘user_name‘];
$data[$key][‘B‘] = "\t" . $value[‘phone‘];
$data[$key][‘C‘] = $value[‘created_at‘];
}
return $data;
}
return [];
}
/**
* 导出数据
* @param $list
*/
public function newExportList($key,$list, $file_name, $total)
{
$arr = [‘A‘ => ‘用户名称‘, ‘B‘ => ‘手机号‘, ‘C‘ => ‘注册时间‘];
if ($total == 1) {
array_unshift($list, $arr); //插入表头
} else {
$total += 1;
}
$title = date(‘Y-m-d‘, time()) . ‘_‘ . $file_name . ‘.csv‘;
$width = array(‘A‘ => 45, ‘B‘ => 35, ‘C‘ => 35);//列宽
$res=exportExcelForURL($title, $list, $width, $total);
if($res){
Redis::set($key,$res);
Redis::EXPIRE($key,600);
}
return [‘code‘ => 200,‘url‘=>$res];
}
/**
* 导出excel 分批保存
* @param $title
* @param $list
* @param $width
*/
function exportExcelForURL($title, $list, $width, $total = 0)
{
$file_name = env(‘EXPORT_DIR‘) . ‘/‘ . $title;
$name=config(‘config.EXCEL_ROUTE‘). $title;
if (!file_exists($file_name)) {
$myfile = fopen($file_name, "w");
fclose($myfile);
}
$excel = \Excel::load($file_name);
$sheet = $excel->getSheet(0);
foreach ($list as $row_key => $row) {
foreach ($row as $key => $value) {
\Log::info($key . ($row_key + $total));
$res = $sheet->setCellValue($key . ($row_key + $total), $value);
}
}
$excel->store(‘csv‘, env(‘EXPORT_DIR‘));
if (count($list)
/**
* 获取下载链接
*
* @param Request $request
* @return void
*/
public function getURL(Request $request)
{
$key=$request->key;
$data[‘url‘]=Redis::get($key);
return success($data);
}
php artisan queue:work --tries=3
上一篇:改进SENet-ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks
下一篇:php进程与信号
文章标题:PHPExecl导出大量数据卡顿问题解决(Laravel实现)
文章链接:http://soscw.com/index.php/essay/44864.html