1点击下载时将查询语句存入数据库
$this->db->insert('excel_export', [
'file_name' => 'orderInfo' . date('YmdHis'),
'path' => 'storage/excel_temp/',
'uid' => $user['uid'],
'type' => 1,
'created_at' => date('Y-m-d H:i:s'),
'count' => $count,
'sql' => str_replace('LIMIT 500 OFFSET 0', '', $this->db->log()[0]),
'number' => 0,
'rate' => 0,
]);
2开启定时任务生成文件并合并
//生成文件
public function createExcel()
{
ExcelExport::where('status', 0)->get()->take(1)->map(function ($item) {
if ($item['type'] == 1 && $item['sql'] != null) {
$this->exportOrder($item);
}
});
}
public function exportOrder($item)
{
$num = 0;
$f = null;
foreach ($this->getCounts($item, function ($fp) use (&$f) {
$f = $fp;
}) as $value) {
$num++;
if (1000 === $num) {
ob_flush();
flush();
$num = 0;
}
foreach ($value as $v) {
$put = json_decode(json_encode($v), true);
fputcsv($f, $put);
}
fclose($f);
}
$this->mergeFile($item, function ($file) use ($item) {
error_reporting(0);
$path = public_path('files/excel_final');
if (!file_exists($path)) {
mkDirs($path);
}
if (file_exists($file)) {
$newFile = $path . '/' . $item['file_name']; //新目录
copy($file, $newFile); //拷贝到新目录
}
self::clearFile($item);
});
}
/**
* 获取阶段导出数据
*/
private function getCounts($item, $handle)
{
$limit = 500;
$pageCount = ceil($item['count'] / $limit);
for ($i = 0; $i < $pageCount; $i++) {
if ($i * $limit >= $item['number']) {
if (!file_exists(public_path('files/excel_temp/' . $item['file_name']))) {
mkDirs(public_path('files/excel_temp/' . $item['file_name']));
}
$file = public_path('files/excel_temp/' . $item['file_name'] . '/_' . $i . '.csv');
touch($file);
$fp = fopen($file, 'w'); //生成临时文件
if ($handle instanceof \closure) {
$handle($fp);
}
$new_list = [];
$order = DB::select($item['sql'] . ' LIMIT ' . $limit . ' OFFSET ' . $i * $limit);
$order_track = DB::table('sync_order_track')
->leftJoin('enum', 'enum.key', '=', 'sync_order_track.status')
->where([
'enum.type' => 'track_status',
])
->whereIn('source_order_id', collect($order)->pluck('source_order_id'))
->get();
collect($order)->map(function ($item) use (&$new_list, $order_track) {
$row = json_decode($item->raw, true);
$track = collect($order_track)->where('source_order_id', $item->source_order_id)->sortBy('flush_date')->last();
$new_list[] = [
'id' => $item->id,
'shop_name' => $item->shop_name,
'products' => join(',', array_column($row['products'], 'title')),
'source_order_id' => $item->source_order_id,
'ship_name' => $item->ship_name,
'tracking_number' => $item->tracking_number,
'ship_time' => $item->ship_time,
'status' => $item->status,
'money' => $row['subtotal_price'] . $row['currency'],
'money_status' => $item->money_time == null ? '未回款' : '已回款',
'money_time' => $item->money_time,
'ship_current_status' => $item->ship_current_status,
'track_message' => $track->value ?? '',
'qs_time' => $track->flush_date ?? '',
'plat_checkout_at' => $item->plat_checkout_at,
];
});
$update = [
'number' => ($i + 1) * $limit > $item['count'] ? $item['count'] : ($i + 1) * $limit,
'rate' => ($i + 1) * $limit / $item['count']
];
if ($update['rate'] >= 1) {
$update['status'] = 1;
$update['rate'] = 1;
$update['path'] = public_path('files/excel_final') . '/' . $item['file_name'];
}
ExcelExport::where('id', $item['id'])->update($update);
yield $new_list;
}
}
}
/**
* 合并文件
*/
private function mergeFile($item, $handle)
{
$fileList = glob(public_path('files/excel_temp/' . $item['file_name'] . '/*'));
$count = count($fileList);
for ($i = 0; $i < $count; $i++) {
if ($i > 0) {
file_put_contents($fileList[0], file_get_contents($fileList[$i]), FILE_APPEND);
}
}
if ($handle instanceof \closure) {
$handle($fileList[0]);
}
}
/**
* 清除文件
*/
private static function clearFile($item)
{
error_reporting(0);
$fileList = glob(public_path('files/excel_temp/' . $item['file_name'] . '/*'));
foreach ($fileList as $value) {
unlink($value);
}
}
3前端查看下载进度 完成导出的可下载,以上方法可实现断点继续下载