做项目的时候,经常会有导出数据的需求,当被导出的数据量较小时,直接实时导出即可。当数据量较大时,就不能实时导出了,会遇到如下问题:

1、内存溢出(Out Of Memory,简称OOM)

2、页面超时

3、单个sheet太大

 这种情况,可以采用预约导出的模式,流程大致是这样:用户点击导出按钮,页面提示正在导出,数据库中生成一条任务,后端定时脚本取出任务,按照该任务的条件生成文件,提示前端用户文件已生成,用户下载该文件。

其中几个技术要点,我说下,首先是要建一个任务表,表结构如下

Task 任务表

id                    自增id

task_name     任务名

task_params  参数

file_url            生成的文件路径

lasttime          完成的时间

createtime      创建时间

status             执行状态 (1初始状态,2正在执行中,3执行成功,4执行失败)

del                  是否有效 (0有效,1被删除)

  后端定时脚本每次取少量的任务,别取太多,不然单个脚本执行的时间太长了,比如这样取select * from task where status=1 and del=0 order by creattime asc limit 5,如果任务比较多,可以用多个定时脚本。

  其次要注意生成excel的时候,要注意控制单个sheet的行数(不要超过1048576行),如果行数太大不利于用户打开查看,生成文件的时候,程序要注意拆分为多个sheet。

  这个定时脚本要注意控制内存,变量及时销毁,防止脚本占用内存太大,导致执行失败。

  后端生成文件成功后,要及时告知前端用户,比如用站内信、短信、websocket等消息机制,这个文件一般保留一段时间后,要有一个清理的程序来清理,否则您的服务器中会堆积大量垃圾文件,占用硬盘空间