导出处理耗时的文件

业务场景

业务部门每月都需要导出上个月(按规定格式处理)的销售数据进行二次统计分析

需求分析

导出频率:每月;导出范围:上个月;按规定格式处理:比较耗时;

本地服务器:每处理100条数据耗时20秒,导出是实时统计,这部分不做更优化处理

线上服务器:未知

初步设计

耗时任务即时导出都是不现实的做法;定时任务导出excel,具体文件可存放本地或云端,界面上提供链接下载。

导出Excel代码实现

//https://github.com/Maatwebsite/Laravel-Excel
use Excel;

.
.
.
//导出excel逻辑
$file_name = '';
$sheet_name = '';
$excel = Excel::create($file_name);
$excel->sheet($sheet_name);

$current_sheet_obj = $excel->setActiveSheetIndex(0)->getSheet();
$first_column = [];//存放列名
$current_sheet_obj->row(1, $first_column);

$rows = [];//数据源
$current_sheet_row = 2;
foreach ($rows as $row) {
    //耗时处理操作得到$row_arr 
    ...

    //插入数据
    $current_sheet_obj->row($current_sheet_row, $row_arr);
    $current_sheet_row++;
}

导出Excel存在问题

已知线上服务器,当数据量到达一定程度时,无法顺利导出excel

优化设计

前提:没有规定必须要excel做复杂的样式;

放弃直接导出excel,先导出txt文本文件,再手动复制到excel;Linux下只要保证有制表符 "\t" 和换行符 "\n" 即可。

导出txt代码实现

use Storage;

.
.
.
//不限制执行时间
set_time_limit(0);
//最大内存
ini_set('memory_limit', '-1');

//导出txt逻辑
$file_path = $file_name.".txt";
$str = "";//拼接表头字符
Storage::disk('local')->put($file_path, $str);

//以二进制的方式追加读写
$file = fopen(storage_path().$file_path, "a+b");

$str = "";
$rows = [];//数据源
foreach ($rows as  $row) {
    //耗时处理操作得到$str
    ...

    //每处理1条数据就写入一次,数据量大时,建议批量写入
    fwrite($file, $str."\n");
}

fclose($file);

导出txt存在问题

使用Storage::disk('local')->append($file_path, $str),数据量到达一定程度时,仍提示内存不足

local.ERROR: exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Out of memory (allocated 1197211648) (tried to allocate 96374400 bytes)' in /var/www/my_project/vendor/league/flysystem/src/Util/MimeType.php:28 Stack trace: #0 {main} [] []

解决:

使用fopen($file_path, "a+b"); //二进制模式追加到文件末尾;

分批处理,每处理100条追加一次文本

最终优化效果

本地服务器:最终顺利导出5W条处理耗时的数据,花费3小时左右。

通过top指令观察,可以看到本地测试服务器(内存1G左右)比较稳定,没有出现内存不足的情况

导出处理耗时的文件

线上服务器:导出5W条处理耗时数据,仅20秒不到,效果还不错:)

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 1

导出CSV格式可以直接用Excel打开

4个月前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!