jeesite poi大批量上传文件崩溃,OOM的解决方法

jeesite poi大批量上传文件崩溃,OOM的解决方法

这几天用jeesite做个银行绩效考核,银行数据过大,一个excel50多M,20多万条数据,字段100多个个,如果用它自带的poi,在循环插入数据库的时候,会造出几百万的对象,瞬间填满内存,而且循环没完成时,还释放不了对象。

当时也在想为什么50M的数据就能填满内存,但网上也没个正式的说法,个人感觉认为,不能单纯认为50Mexcel,传上去就是50M,因为每条数据插入时会产生代码片,每片都很大,那就是几十万的代码片段塞入内存,瞬间就炸。

那来说说解决的办法,首先你要下载个阿里巴巴的easyexcel,地址如下
https://github.com/alibaba/easyexcel

下载后你导入eclipse,它是个maven工程导入,然后你先试验下能不能用,github都有试验教程,完成后你用eclipse的maven功能导出成jar包,这里maven工程导出成jar包,百度有说明,理论上不倒成jar也能用,但我觉得导成jar包更方便。
我完成后是这样的在这里插入图片描述
然后就可以使用啦,你在你要使用的地方加上如下代码,

//注意你要是用的jeesite的话它自带的poi传入就是MultipartFile对象
//那你就可以用file.getInputStream()直接获取流
InputStream inputStream = file.getInputStream();
DgkListener dgkListener = new DgkListener();
EasyExcelFactory.readBySax(inputStream, new Sheet(3, 1, ReadModel.class), dgkListener);
inputStream.close();

以上代码中做添加到数据库的操作是在DgkListener类中,我个人的如下:

    //这里我插入数据库的操作是在service中完成,但这个类没上交spring管理所以要先引入service
    private static DgckbaseigkBaseService dgckbaseigkBaseService = SpringContextHolder.getBean(DgckbaseigkBaseService.class);
    private List  data = new ArrayList();

    @Override
	public void invoke(Object object, AnalysisContext paramAnalysisContext) {
        if(data.size()<=1000){
			data.add((ReadModel) object);
        }else {
            doSomething();
            data = new ArrayList();
            //这里是我遇到的坑,原来下下来的没用下面这段代码,但这样会造成数据少存入一行,莫名其妙
            //搞了半天,我在这里加上如下代码,就可以啦。也不知道写这个人的人是怎么用的,难道他们没少?
            data.add((ReadModel) object);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        doSomething();
    }
    
    public void doSomething(){
    	//我直接每10001条传入次service,做数据库插入工作,完成后也是每10001次提交次事务
    	//事务提交在service最好添加,不然会很慢
    	dgckbaseigkBaseService.insertDb(data);
    }

总的来说就这样了,一开始这个oom很难解决,网上很多文章教程也有,其实这个的原理跟poi官方的解决办法,先把文件上传到服务器形成cscv格式的文档,然后程序再一行行的去读这个文件,读完后删除。

easyexcel可能也是用这种方法,没细看源码。

说这么多希望对你有所帮助。

你可能感兴趣的:(jeesite)