发明内容
鉴于上述现有技术的不足,本发明的目的在于提供导出excel数据的方法、存储介质及电子设备,旨在解决现有技术中excel数据导出方式存在的稳定性差、可导出的数据量有限等问题。
本发明的技术方案如下:
一种基于多线程的多点续作方式导出excel数据的方法,其中,包括步骤:
A、根据所需导出的excel数据总页数和每个sheet表单所需写入的页码数计算需要的sheet表单数量;
B、生成SXSSFWorkbook对象,并针对每个sheet表单开启一个线程,将对应的excel数据写入SXSSFWorkbook对象中;
C、当各线程执行完毕后,通过IO输出SXSSFWorkbook对象。
所述的基于多线程的多点续作方式导出excel数据的方法,其中,所述步骤A具体包括:
A1、预先设置每页查询数量和每个sheet表单最多可以写入的页码数;
A2、获取excel数据总页数;
A3、根据excel数据总页数和每个sheet表单所需写入的页码数计算需要的sheet表单数量。
所述的基于多线程的多点续作方式导出excel数据的方法,其中,所述步骤B具体包括:
B1、创建SXSSFWorkbook对象;
B2、针对每个sheet表单开启一个线程,创建sheet表单以及相应表头信息,计算sheet表单所对应的页面范围;
B3、分页查询excel数据,并将对应页面范围内的excel数据写入SXSSFWorkbook对象。
所述的基于多线程的多点续作方式导出excel数据的方法,其中,所述步骤C具体包括:
C1、监控各子线程是否执行完毕;
C2、当所有子线程都执行完毕后,将生成的SXSSFWorkbook对象进行输出。
所述的基于多线程的多点续作方式导出excel数据的方法,其中,所述步骤A1中,每页查询数量为pageSize,每个sheet表单最多可以写入的页码数为sheetSize,pageSize*sheetSize≤1048576。
所述的基于多线程的多点续作方式导出excel数据的方法,其中,所述步骤B3中,每写完一页excel数据时,记录当前最后一行的行数,返回给调用方,作为调用方下一次写入excel数据的参数继续写入,直至对应sheet表单需要记录的excel数据全部写入SXSSFWorkbook对象中。
所述的基于多线程的多点续作方式导出excel数据的方法,其中,所述步骤B3中,在写完一页excel数据后,页码加1,并判断页码是否达到对应sheet表单最大页码数,若是则写入完毕,若否则继续写入。
所述的基于多线程的多点续作方式导出excel数据的方法,其中,所述步骤C2中,将生成的SXSSFWorkbook对象通过IO流的形式进行输出。
一种存储介质,其中存储有多条指令,其中,所述指令适于由处理器加载并执行:
根据所需导出的excel数据总页数和每个sheet表单所需写入的页码数量计算需要的sheet表单数量;
生成SXSSFWorkbook对象,并针对每个sheet表单开启一个线程,将对应的excel数据写入SXSSFWorkbook对象中;
当各线程执行完毕后,通过IO输出SXSSFWorkbook对象。
一种电子设备,其中,包括:
处理器,适于实现各指令,以及
存储介质,适于存储多条指令,所述指令适于由处理器加载并执行:
根据所需导出的excel数据总页数和每个sheet表单所需写入的页码数量计算需要的sheet表单数量;
生成SXSSFWorkbook对象,并针对每个sheet表单开启一个线程,将对应的excel数据写入SXSSFWorkbook对象中;
当各线程执行完毕后,通过IO输出SXSSFWorkbook对象。
有益效果:本发明采用多线程,通过多点续作的方式,加快java对象占用的内存空间回收,降低内存占用,增强系统稳定性,扩展可导出的数据量,提高响应效率。
具体实施方式
本发明提供导出excel数据的方法、存储介质及电子设备,为使本发明的目的、技术方案及效果更加清楚、明确,以下对本发明进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
请参阅图1,图1为本发明一种基于多线程的多点续作方式导出excel数据的方法,其中,包括步骤:
S1、根据所需导出的excel数据总页数和每个sheet表单所需写入的页码数计算需要的sheet表单数量;
S2、生成SXSSFWorkbook对象,并针对每个sheet表单开启一个线程,将对应的excel数据写入SXSSFWorkbook对象中;
S3、当各线程执行完毕后,通过IO输出SXSSFWorkbook对象。
本发明基于POI,采用多线程,通过多点续作的方式,加快java对象占用的内存空间回收,降低内存占用,增强系统稳定性,扩展可导出的数据量,提高响应效率。其中的POI是指开源的excel处理工具包。
POI提供了SXSSFWorkbook对象,每个sheet表单可以写入一百万左右的数据,并且可以控制内存中的记录数据超过设置的限制时,写入磁盘,降低SXSSFWorkbook对象占用的内存空间。
具体地,所述步骤S1具体包括:
S11、预先设置每页查询数量和每个sheet表单最多可以写入的页码数;
S12、获取excel数据总页数;
S13、根据excel数据总页数和每个sheet表单所需写入的页码数计算需要的sheet表单数量。
在所述步骤S11中,预先设置每页查询数量pageSize和每个sheet表单最多可以写入的页码数sheetSize,其中,pageSize*sheetSize<=1048576,以避免报java.lang.IllegalArgumentException异常。
在所述步骤S12和步骤S13中,使用分页查询记录,获取excel数据总页数和sheet表单数量。由于每个sheet表单所需写入的页码数以及excel数据总页数是固定的,所以将excel数据总页数除以每个sheet表单所需写入的页码数即等于sheet表单数量(每个sheet表单所需写入的页码数相同)。
进一步,所述步骤S2具体包括:
S21、创建SXSSFWorkbook对象;
S22、针对每个sheet表单开启一个线程,创建sheet表单以及相应表头信息,计算sheet表单所对应的页面范围;
S23、分页查询excel数据,并将对应页面范围内的excel数据写入SXSSFWorkbook对象。
在所述步骤S21中,首先创建SXSSFWorkbook对象。
在所述步骤S22中,针对每个sheet表单均开启一个线程。创建sheet表单,并调用decorateHead方法创建相应表头。另外在调用decorateHead方法时还同时返回SXSSFWorkbook对象和记录当前行号的map对象。
decorateHead方法的代码如下:
public Map<String,Object>decorateHead(Map<String,Object>exportDataInfo,intsheetNum,String titleName,String[]heads)throws Exception
参数:
exportDataInfo:包含SXSSFWorkbook的引用对象workbook,第一次调用时,workbook为空,会创建一个;
sheetNum:Sheet表单的位置;
titleName:Sheet表单名称,当第一次创建调用该方法时,直接使用,后面再调用时,创建sheet表单时拼接;
sheetNun进去,区分不同的sheet表单;heads:表头栏目名称;
返回值:
exportDataInfo,包含:
workbook:SXSSFWorkbook对象
rowIndex:当前记录的行数
抛出:
java.lang.Exception
在所述步骤S23中,每写完一页excel数据时,记录当前最后一行的行数(即当前行号),返回给调用方,作为调用方下一次写入excel数据的参数继续写入,直至对应sheet表单需要记录的excel数据全部写入SXSSFWorkbook对象中。也就是,每个线程调用decorateExcel方法逐页将excel数据写入SXSSFWorkbook对象。
另外,在写完一页excel数据后,页码加1,并判断页码是否达到对应sheet表单最大页码数(即sheet表单规定的页码数),若是则写入完毕,若否则继续写入,直至页码达到sheet表单最大页码数。
本发明最有效的优化就是减少java对象所占用的空间,这是基于Executor框架的线程管理,运用多点续作的思想,在每次处理数据后将下一次需要使用的行记录等参数存入map对象,作为返回值回传给调用方,调用方作为下一次调用的参数。
decorateExcel方法的代码如下:
public Map<String,Object>decorateExcel(Map<String,Object>exportDataInfo,int sheetNum,String[]column,List<?>data)throws Exception
参数:
exportDataInfo:包含:
workbook:SXSSFWorkbook的引用对象;
rowIndex:当前记录的行数
sheetNum:Sheet表单的位置;
column:导出数据在实体对象中对应的属性;
data:本次查询要写入的数据;
返回值:
java.util.Map<String,Object>对象,包含:
workbook:SXSSFWorkbook对象
rowIndex:当前记录的行数
抛出:
java.lang.Exception
进一步,所述步骤S3具体包括:
S31、监控各子线程是否执行完毕;
S32、当所有子线程都执行完毕后,将生成的SXSSFWorkbook对象进行输出。
在所述步骤S31中,主线程监控各个子线程是否执行完毕。
在所述步骤S32中,当监控到所有子线程都执行完毕后,调用doExport方法,将前面步骤中生成的SXSSFWorkbook对象输出给用户。优选的,将生成的SXSSFWorkbook对象通过IO流的形式进行输出。由于采用的IO流的形式,故可以通过设置response.setBufferSize(int size)控制占用内存的大小。
doExport方法的代码如下:
doExport
public void doExport(HttpServletRequest request,HttpServletResponseresponse,String excelName,SXSSFWorkbook hssfWorkbook)
参数:
request:包含:客户端的请求;
response:客户端的相应;
excelName:文件名称;
hssfWorkbook:要输出的文件对象。
通过测试发现,使用同样的JVM(JAVA虚拟机)设置,都成功导出一百万条记录,使用分页方案可以将消耗的最大内存降低至原来的一半,修改JVM新生代和老年代的内存空间以后,使用分页方案导出方案消耗最大内存降低至原来的20%时可以正常导出,而非分页方案则直接报OutOfMemoryException异常。另外,由于excel2007sheet表单数量不受限制,通过创建多个sheet表单,可以根据业务方需要,不受限制的扩展导出的记录数量,可方便地导出千万级别的数据。
如果需要导出大量数据时,只需要在原来引入POI的工具包的基础上,再引入该工具类,使用多点续作的多线程方式即可实现一次性导出大量数据,而不会造成内存溢出,提高了系统稳定性,同时减少了业务方的工作量。
本发明还提供一种存储介质,其中存储有多条指令,其中,所述指令适于由处理器加载并执行:
根据所需导出的excel数据总页数和每个sheet表单所需写入的页码数量计算需要的sheet表单数量;
生成SXSSFWorkbook对象,并针对每个sheet表单开启一个线程,将对应的excel数据写入SXSSFWorkbook对象中;
当各线程执行完毕后,通过IO输出SXSSFWorkbook对象。
关于上述存储介质的具体技术细节在前面的方法中已有详述,故不再赘述。
本发明还提供一种电子设备,其中,包括:
处理器,适于实现各指令,以及
存储介质,适于存储多条指令,所述指令适于由处理器加载并执行:
根据所需导出的excel数据总页数和每个sheet表单所需写入的页码数量计算需要的sheet表单数量;
生成SXSSFWorkbook对象,并针对每个sheet表单开启一个线程,将对应的excel数据写入SXSSFWorkbook对象中;
当各线程执行完毕后,通过IO输出SXSSFWorkbook对象。
关于上述电子设备的具体技术细节在前面的方法中已有详述,故不再赘述。
综上所述,本发明采用多线程,通过多点续作的方式,加快java对象占用的内存空间回收,降低内存占用,增强系统稳定性,扩展可导出的数据量,提高响应效率。
应当理解的是,本发明的应用不限于上述的举例,对本领域普通技术人员来说,可以根据上述说明加以改进或变换,所有这些改进和变换都应属于本发明所附权利要求的保护范围。