牛逼!这款Excel处理工具太强了!

哈喽,我是老鱼,一名致力于在技术道路上的终身学习者、实践者、分享者!

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存! 今天老鱼就给大家介绍一款由阿里巴巴开源的Excel处理工具,简直太强了!以使用简单、节省内存著称!

Easy Excel

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)

官方测试,64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本),这不强吗?!

快速接入

官方不仅有详细的开发文档,而且每一个功能接口都有对应demo供开发者们参考。

1. 依赖

<dependency>    <groupId>com.alibaba</groupId>    <artifactId>easyexcel</artifactId>    <version>3.2.0</version></dependency>

2.读Excel

# 创建实体类对象@Getter@Setter@EqualsAndHashCodepublic class DemoData {    private String string;    private Date date;    private Double doubleData;}
    /**     * 最简单的读     * <p>     * 1. 创建excel对应的实体对象 参照{@link DemoData}     * <p>     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}     * <p>     * 3. 直接读即可     */    @Test    public void simpleRead() {        // 写法1:JDK8+ ,不用额外写一个DemoDataListener        // since: 3.0.0-beta1        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭        // 这里每次会读取100条数据 然后返回过来 直接调用使用数据就行        EasyExcel.read(fileName, DemoData.class, new PageReadListener<DemoData>(dataList -> {            for (DemoData demoData : dataList) {                log.info("读取到一条数据{}", JSON.toJSONString(demoData));            }        })).sheet().doRead();        // 写法2:        // 匿名内部类 不用额外写一个DemoDataListener        fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭        EasyExcel.read(fileName, DemoData.class, new ReadListener<DemoData>() {            /**             * 单次缓存的数据量             */            public static final int BATCH_COUNT = 100;            /**             *临时存储             */            private List<DemoData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);            @Override            public void invoke(DemoData data, AnalysisContext context) {                cachedDataList.add(data);                if (cachedDataList.size() >= BATCH_COUNT) {                    saveData();                    // 存储完成清理 list                    cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);                }            }            @Override            public void doAfterAllAnalysed(AnalysisContext context) {                saveData();            }            /**             * 加上存储数据库             */            private void saveData() {                log.info("{}条数据,开始存储数据库!", cachedDataList.size());                log.info("存储数据库成功!");            }        }).sheet().doRead();        // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去        // 写法3:        fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();        // 写法4        fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";        // 一个文件一个reader        try (ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build()) {            // 构建一个sheet 这里可以指定名字或者no            ReadSheet readSheet = EasyExcel.readSheet(0).build();            // 读取一个sheet            excelReader.read(readSheet);        }    }

3.写Excel

# 创建实体类对象@Getter@Setter@EqualsAndHashCodepublic class DemoData {    @ExcelProperty("字符串标题")    private String string;    @ExcelProperty("日期标题")    private Date date;    @ExcelProperty("数字标题")    private Double doubleData;    /**     * 忽略这个字段     */    @ExcelIgnore    private String ignore;}
    /**     * 最简单的写     * <p>     * 1. 创建excel对应的实体对象 参照{@link DemoData}     * <p>     * 2. 直接写即可     */    @Test    public void simpleWrite() {        // 注意 simpleWrite在数据量不大的情况下可以使用(5000以内,具体也要看实际情况),数据量大参照 重复多次写入        // 写法1 JDK8+        // since: 3.0.0-beta1        String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭        // 如果这里想使用03 则 传入excelType参数即可        EasyExcel.write(fileName, DemoData.class)            .sheet("模板")            .doWrite(() -> {                // 分页查询数据                return data();            });        // 写法2        fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭        // 如果这里想使用03 则 传入excelType参数即可        EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());        // 写法3        fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";        // 这里 需要指定写用哪个class去写        try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) {            WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();            excelWriter.write(data(), writeSheet);        }    }

还有更多用法比如读取多个sheet、读取表头信息、读取公式;写入指定的列、复杂头写入;列表填充、数据量大的填充等等,你能想到用到的功能Easy Excel都能实现!

Easy Excel 可以快速的读取excel中的数据;映射excel和实体类,让代码变的更加简洁;而且在读写大文件时使用磁盘做缓存,更加的节约内存,老鱼力荐!

End

我是老鱼,白天敲代码,晚上搞自媒体。

**********************

全部评论

相关推荐

04-21 11:22
已编辑
中华女子学院 UE4
耐心学习_佩可officical:直接举报他,佬,违反劳动法我记得boss会下架
点赞 评论 收藏
分享
04-18 15:58
已编辑
门头沟学院 设计
kaoyu:这一看就不是计算机的,怎么还有个排斥洗碗?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务