新版导出功能说明
来自技术开发小组内部wiki
背景:
解决导出困难,线上导出经常出现500错误,导致的超时错误,由于PHPEXCEl(目前官方已经停止更新)的自身在导出同事会占用大部分内存,导致内存溢出崩溃,经过商讨,整合了一套主流的POI导出类(基于JAVA实现),原理和PHPEXCEL功能一样,但功能更高效。
核心配置信息
开始生成导出接口
http://192.168.0.210:7201/excelGen/genExcel.do?key=xxx 线上生成excel内网地址,只停供内网访问
查看生成生成的的任务:
redis配置:
测试机 192.168.30.225 端口6380,4号库
生产机 192.168.30.225 端口6380,4号库
整体目标:
PHP将excel文件数据写入redis,然后调用Java接口触发生成excel的动作(拼装需要导出的数据和返回值,返回值的格式是固定的),Java接口获取接口参数,完成excel输出.excel支持多工作表
注意:测试机和线上的redis都是4好库,只是端口不一样,别忘了这一点,不然就坏菜了。
EXCEL的生成数据包含两部分:
第一部分是excel的基础信息(可以理解导出的自定义信息,如标题样式等,用set)
第二部分是是表格具体数据(redis命令用rpush,数据量大可以使用pipeline,优化插入性能)
命名规则:
Excel基础信息,key值自己定义建议”excel_”开头,要防止重复(可以利用time()+rand(1000,999)随机数来生成)
Key值 excel_1533031368388 ,对应的内容数据list名称为excel_1533031368388_data_xx,其中xx可以是工作表序号,该接口支持单excel多工作表
第一部分的生成数据结构:
值内容为json形式字符串(以下为格式化后的样式),样例如下
{
//固定写数字1
status: 1,
//php输入时该值为””,输出完成时这个值变为excel文件的访问路径
saveFileName: "",
//每个工作表的信息
sheetInfos: [
{
//工作表首行标题
titles: [
"名字",
"数量",
"价格",
"日期",
"时间"
],
//工作表名字
sheetName: "sheet_1533094208859_0",
//和titles对应列的格式信息,数字格式
//1-文本
//2-整数
//3-double类型
//4-日期格式yyyy-m-d
//5-时间格式 yyyy-m-d h:mm:ss
//目前只支持这几种格式 后续可以扩展.
colType: [
1,
2,
3,
4,
5
],
//工作表内容存储的队列名称,队列数据采用rpush方式插入redisDataQueueName: "excel_1533094208859_data_0"
},………………
//其他工作表信息
]
}
第二部分的值:
队列里的单条json字符串:
["张三","0","123.45","2018-03-13","2018-03-13 12:12:34"]
生成完以后,再通过redisDataQueueName的值遍历需要插入的数据,单条值rpush到队列进去,完成后,请求接口:
注意:key值通过自定义返回统一的标识,进行接口的返回处理。
接口返回值:
{"code":1000,"message":"done","jobInfo":{"status":2,"saveFileName":"http://192.168.28.253:7201/20180802/1533194403131.xlsx","sheetInfos":[{"titles":["名字","数量","价格","日期","性别"],"sheetName":"sheet_15331943533300_0","colType":[1,2,2,4,1],"redisDataQueueName":"excel_15331943533300_data_0"},{"titles":["订单号","用户UID","交易时间"],"sheetName":"sheet_15331943533300_1","colType":[1,2,5],"redisDataQueueName":"excel_15331943533300_data_1"}]}}
返回值说明:
//1000-任务正常结束
//1001-这个任务已经提交过了.正在运行
//1002-找不到这个key
//1003-生成excel报错了,通知java开发吧 #__#
//1005-任务已经结束了,由于任务结束后10分钟内还能查看到结果
注意:saveFilename为每次生成的路径,直接导出把地址取出来,每次调用后会生成不同的key
注意:返回后我们只需要判断1000和1005为正常返回,其他的按照相关接口给予页面提示。
调用方法:
后台已经整合了导出的实现,我们只需要按照指定的格式进行数据拼装,调用返回待有地址的url下载地址直接进行下载:
$this->load->library ( "JavaExcelHandle", "", "excelhandle" );
$data = array(
'headeTitle' =>array(
//导出的表头,多个工作表,用array()单独定义,下面一样。
),
'headerType' =>array(
//导出的每列的类型 ,目前支持1(文本) 2 (整数)3 (double类型)4 (日期格式yyyy-m-d)5(时间格式 yyyy-m-d h:mm:ss)
),
//数据结构体
'data' =>array(
//如果只有一个工作表,直接写内容,不需要重新定义数组
),
//指定工作表名称
'sheetName' =>array('测试文档工作表','工作表名称2'), //注意此处有几个工作表就写几个,和data的长度保持一致,不需要用二维定义
//注意 以上三个定义的结构体支持多个工作表的导出格式,
);
获取导出的接口数据内容:
$this->excelhandle->save_excel($data,1);
如果导出的多个工作表,第二个参数追加实际的导出工作表格式,2就导出一个带两个工作表的文件。