这篇文章将为大家详细讲解有关Java环境中如何实现提高Excel读写效率,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
公司主营业务:成都网站制作、网站设计、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联公司是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联公司推出静宁免费做网站回馈大家。问题1. 仅使用简单的导入导出功能,但每次业务的数据对象结构不同,需要重新编写处理方法,很麻烦!
解决方法
将Excel处理逻辑抽取出来,封装成工具类。
封装条件
与大多数Java API一样,POI把更多的精力放在高级功能的处理上,比如Formula(公式)、Conditional Formatting(条件格式)、Zoom(缩放)等。对于仅仅做数据导入导出功能的API User,很少使用这些高级特性,这允许API用户对POI的使用进行简单的封装。
封装方式
无论是读是写,我们都需要解决Excel中的Columns(列)与Java数据对象Fields(字段)的映射关系,将这种映射关系作为参数(Map对象HashMap或LinkedHashMap),传递给工具类。
对于Columns不难理解,它可以是有序的数字或字母,也可以是其它字符串用来作为首行,表示该列数据的含义。
对于Fields,它的处理需要兼容复杂情况,如下:
反射
首先想到,也是大多数封装者都在使用的方式是就是Reflection API,从上文 函数编程 章节我们了解到,反射重量级,会降低代码的性能,同时对复杂情况的处理支持性不够好。
反射+注解
这种方式可以更好的支持复杂情况,但是反射依然会降低性能,同时注解对数据对象会造成代码侵入,而且对该工具类封装者的其他使用者无疑会增加学习成本。
匿名内部类
这种方式也可以很好的支持复杂情况,但是使用匿名内部类的语法显然患有“垂直问题”(这意味着代码需要太多的线条来表达基本概念),太过冗杂。至于性能,应该也不如直接传递函数来的快吧。
函数接口(Lambda)
这种方式是基于第5条方法调用的字节码指令invokeDynamic实现的,直接传递函数代码块,很好的支持复杂情况,性能较高,代码编写更简单结构更加简洁,而且对数据对象代码零侵入。
当然如果你还没有使用Java1.8或更高版本,那么你可以参考匿名内部类或反射+注解,不过还是推荐反射+注解,Alibaba/easyexcel【/tupian/20230522/easyexcel】对你来说会是不错的选择。
问题2. Excel导入或导出数据量比较大,造成内存溢出或频繁的Full GC,该如何解决?
解决方法
原理
POI的使用对我们来说很常见,对下面两个概念应该并不陌生:
但是对于eventmodel和streaming.SXSSFWorkbook就很少接触了,它们是POI提供的专门用来解决内存占用问题的low level API(低级API),使用它们可以读写数据量非常大的Excel,同时可以避免内存溢出或频繁的Full GC。【https://poi.apache.org/components/spreadsheet/how-to.html】
eventmodel,用来读Excel,并没有将Excel整个加载到内存中,而是允许用户从InputStream每读取一些信息,就交给回调函数或监听器,至于丢弃,存储还是怎么处理这些内容,都交由用户。
streaming.SXSSFWorkbook,用来写Excel(是对XSSFWorkbook的封装,仅支持.xlsx),通过滑动窗口来实现,只在内存中保留滑动窗口允许存在的行数,超出的行Rows被写出到临时文件,当调用write(OutputStream stream)方法写出内容时,再直接从临时内存写出到目标OutputStream。SXSSFWorkbook的使用会产生一些局限性。
解决途径
/tupian/20230522/gridexcel 基于Java函数编程(Lambda),支持流式API,使用环境Java1.8或更高,学习成本:
Lambda
/tupian/20230522/easyexcel 基于反射+注解+监听器,使用环境Java1.6或以上,学习成本:模型注解
实际上POI官网已经给了用户使用示例,而上述两个工具都只是做了自己的封装实现,使用者只需要拿来用就好。
快速使用
com.github.liuhuagui gridexcel 2.2