新版导出功能说明

来自技术开发小组内部wiki
跳转至: 导航搜索
背景:

解决导出困难,线上导出经常出现500错误,导致的超时错误,由于PHPEXCEl(目前官方已经停止更新)的自身在导出同事会占用大部分内存,导致内存溢出崩溃,经过商讨,整合了一套主流的POI导出类(基于JAVA实现),原理和PHPEXCEL功能一样,但功能更高效。

核心配置信息

开始生成导出接口

测试机生成excel内网地址,只停供内网访问 http://192.168.28.253:7201/excelGen/genExcel.do?key=xxx 测试机生成内网地址,只提供内网访问


http://192.168.0.210:7201/excelGen/genExcel.do?key=xxx 线上生成excel内网地址,只停供内网访问

查看生成生成的的任务:
http://192.168.28.253:7201/excelGen/testQueryExcelInfo.do?key=xxx

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到队列进去,完成后,请求接口:
http://192.168.0.210:7201/excelGen/genExcel.do?key=excel_15331925783068
注意: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就导出一个带两个工作表的文件。