clob字段怎么导出_3行代码实现Excel的导入导出

点击上方“蓝色字体”,选择“设为星标”

第一时间关注最新文章!

✨一起快乐的学习、成长、热爱生活✨  

一、前言

关于导出 Excel 文件,可以说是大多数服务中都需要集成的功能。那么,要如何快速地(偷懒地)去实现这个功能呢?

你可能第一想法是:这还不简单?用 Apache 开源框架 poi, 或者 jxl 都可以实现啊。面向百度编程,把代码模板 copy 下来,根据自己的业务再改改,能有多难?

嗯.. 的确不难,但是你的代码可能是下面这个熊样子的:

80876d13c02e6ca24adcd51a3ec14df4.png

上面这段代码看上去是不是又臭又长呢?今天,将教您如何使用 3 行代码搞定 Excel 文件生成功能!

47f28a8c81e71fc0107dbd8076d702d5.png

二、Apache poi、jxl 的缺陷

在说如何实现之前,我们先来讨论一下传统 Excel 框架的不足!除了上面说的,Apache poi、jxl 都存在生成 excel 文件不够简单优雅快速外,它们都还存在一个严重的问题,那就是非常耗内存严重时会导致内存溢出

POI 虽然目前来说,是 excel 解析框架中被使用最广泛的,但这个框架并不完美。

为什么这么说呢?

开发者们大部分使用 POI,都是使用其 userModel 模式。而 userModel 的好处是上手容易使用简单,随便拷贝个代码跑一下,剩下就是写业务转换了,虽然转换也要写上百行代码,但是还是可控的。

然而 userModel 模式最大的问题是在于,对内存消耗非常大,一个几兆的文件解析甚至要用掉上百兆的内存。现实情况是,很多应用现在都在采用这种模式,之所以还正常在跑是因为并发不大,并发上来后,一定会OOM或者频繁的 full gc。

三、阿里出品的 EasyExcel,安利一波

什么是 EasyExcel? 见名知意,就是让你轻松的操作 Excel 。先来看下 EasyExcel 官方截图:

3308319bdab1df7edff37f96c5fa5e48.png

官方对其的简介是:

快速、简单避免OOM的java处理Excel工具!

四、EasyExcel 解决了什么

主要来说,有以下几点:

  • 传统 Excel 框架,如 Apache poi、jxl 都存在内存溢出的问题;

  • 传统 excel 开源框架使用复杂、繁琐;

  • EasyExcel 底层还是使用了 poi, 但是做了很多优化,如修复了并发情况下的一些 bug, 具体修复细节,可阅读官方文档https://github.com/alibaba/easyexcel;

五、快速上手

5.1 添加依赖

com.alibaba

easyexcel

1.1.2-beta5

5.2 三行代码搞定 Excel 导入导出

写Excel 

/**
     * 最简单的写
     *

1. 创建excel对应的实体对象 参照{@link DemoData}
     *

2. 直接写即可
     */


    @Test
    public void simpleWrite() {
        // 写法1
        String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        // 如果这里想使用03 则 传入excelType参数即可
        EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
    }

上面这段示例代码中,有一个点很重要:

  • ①:DemoData这个对象就是要写入 Excel 的数据模型对象,等等,你这好像不行吧?表头 head,以及每个单元格内的数据顺序都没指定,能达到想要的效果么?别急,后面会讨论这块!

回过头来,我们来看看 DemoData 这个对象内部到底有什么幺蛾子!

@Data
public class DemoData {
    @ExcelProperty("字符串标题")
    private String string;
    @ExcelProperty("日期标题")
    private Date date;
    @ExcelProperty("数字标题")
    private Double doubleData;
    /**
     * 忽略这个字段
     */
    @ExcelIgnore
    private String ignore;
}

ExayExcel 提供注解的方式, 来方便的定义 Excel 需要的数据模型:

  • :通过 @ExcelProperty 注解来指定每个字段的列名称,以及下标位置

同时,上面定义的 data() 方法也很简单,通过循环,创建一个写入模型的 List 集合:

private List data() {Listlist = new ArrayList();for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字符串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);list.add(data);
        }return list;
    }

废话不多说,这个快速接入的案例也介绍的差不多了,跑一跑单元测试看下实际效果:

11f468843d288a250cd1645c5c538a20.png

怎么样,效果还是挺棒棒的!

读Excel 

读excel是通过继承AnalysisEventListener监听器并重写invoke方法来实现的

// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class DemoDataListener extends AnalysisEventListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    Listlist = new ArrayList();/**
     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */private DemoDAO demoDAO;public DemoDataListener() {// 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
        demoDAO = new DemoDAO();
    }/**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param demoDAO
     */public DemoDataListener(DemoDAO demoDAO) {this.demoDAO = demoDAO;
    }/**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     * one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Overridepublic void invoke(DemoData data, AnalysisContext context) {
        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));list.add(data);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (list.size() >= BATCH_COUNT) {
            saveData();// 存储完成清理 listlist.clear();
        }
    }/**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        LOGGER.info("所有数据解析完成!");
    }/**
     * 加上存储数据库
     */private void saveData() {
        LOGGER.info("{}条数据,开始存储数据库!", list.size());
        demoDAO.save(list);
        LOGGER.info("存储数据库成功!");
    }
}

通过EasyExcel.read读取文件内容

/**
     * 最简单的读
     *

1. 创建excel对应的实体对象 参照{@link DemoData}
     *

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
     *

3. 直接读即可
     */


    @Test
    public void simpleRead() {
        // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
        // 写法1:
        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
    }

后面有时间继续写一下如何动态生成Excel内容,自定义表头以及内容样式,以及合并单元格

六、需要注意的点

6.1 写入大数据时,需分片

比如说,我们需要从数据库中查询出数据量较大时,我们需要在业务层做分片处理,也就是,我们需要分多次查询,再写入,防止内存溢出 OOM.

6.2 Excel 最大行数问题

Excel 03, 07 版本均有行数、列数的限制:

版本最大行最大列
Excel 200365536256
Excel 2007104857616384

csv 由于是文本文件,实际上没有最大行数的限制,但是用 Excel 客户端打开还是多了不显示。

也就是说,如果你想写入更多的行数是不行的,强行这么做,程序会报类似如下异常

Invalid row number (1048576) outside allowable range (0..1048575)

如何解决呢?

  1. 分多个 Excel 文件写入;

  2. 同一个 Excel 文件,分多个 Sheet 写入;

七、总结

今天主要给小伙伴介绍了 EasyExcel, 为什么要使用它,以及演示了相关示例代码。当然了,EasyExcel 除了写 Excel 文件外,它还有快速读取 Excel 的功能,由于本文主要介绍的是:如何快色地实现 Excel 文件生成,所以就没有介绍了,有兴趣的小伙伴们,也可以去 GitHub 官网去去查看相关文档。

最后,祝您看完本文后有所收获,下期见!

 近期热文:

  • 五分钟搞懂什么是红黑树,及其平衡规则!

  • 如何优雅地在 Spring Boot 中使用自定义startter

  • 一文带您搞清什么是 Spring Boot 2.x

 // END      作者:ruok085,善良且热爱生活的小青年。  一起学习、成长、温情的热爱生活。

 Follow Me 

ec0962af69413e3d3580a55b20adaf23.png

不言而喻i

希望这篇文章可以帮到你~

欢迎大家点个在看,分享至朋友圈

你我都成为发光之人,“在看+点赞+分享”~(疯狂暗示)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值