美文网首页从零开始学springboot
37. 从零开始学springboot-集成EasyExcel读

37. 从零开始学springboot-集成EasyExcel读

作者: 码哥说 | 来源:发表于2020-04-25 16:43 被阅读0次

    前言

    小编最近使用springboot集成使用EasyExcel时发现了一个坑

    EasyExcel

    EasyExcel是由阿里巴巴开发团队提供的一套操作excel的工具, 与常用的POI区别就在于如下

    1. POI对大数据处理起来会引起OOM内存溢出, EasyExcel对此进行了优化, 对内存的占用极大的优化,同时允许分批处理数据

    2. POI对于读写EXCEL操作复杂, 而EasyExcel只需几行代码即可完成

    注意点

    EasyExcel 版本更新快,不同版本 API 均有不同,有些已经废弃,所以,大家查看文档时,务必找到对应版本的!

    SpringBoot集成EasyExcel

    SpringBoot可以很方便的集成EasyExcel

    添加依赖到pom.xml

    <!-- EasyExcel依赖 -->
    <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>easyexcel</artifactId>
         <version>2.2.0-beta2</version>
    </dependency>
    

    使用上也是很简单,咸鱼君就举个简单的例子, 将excel转换为java 实体类来读取

    先定义一个User的实体

    package com.mrcoder.frameservice.model.po;
    import javax.persistence.Table;
    import com.alibaba.excel.annotation.ExcelProperty;
    import lombok.Data;
    //import lombok.Getter;
    //import lombok.Setter;
    /**
     * @Description: User实体类
     * @author: mrcoder
     */
    //@Getter
    //@Setter
    @Data
    @Table(name = "frame_user")
    public class User extends BaseEntity {
        private static final long serialVersionUID = -6525290662533134200L;
        @ExcelProperty(index = 1)
        private String name;
    
        @ExcelProperty(index = 2)
        private String nickName;
    
        @ExcelProperty(index = 3)
        private Integer age;
    
        @ExcelProperty(index = 4)
        private String email;
    
        @ExcelProperty(index = 5)
        private String phone;
    
        private Integer status;
    }
    

    而后定义一个监听器

    package com.mrcoder.frameservice.excel;
    
    import com.alibaba.excel.context.AnalysisContext;
    import com.alibaba.excel.event.AnalysisEventListener;
    import com.alibaba.fastjson.JSON;
    import lombok.extern.slf4j.Slf4j;
    import com.mrcoder.frameservice.model.po.User;
    import java.util.ArrayList;
    import java.util.List;
    
    @Slf4j
    public class UserModelListener extends AnalysisEventListener<User> {
    
        //自定义用于暂时存储data
        private List<User> dataList = new ArrayList<User>();
    
        @Override
        public void invoke(User user, AnalysisContext context) {
            log.info("解析到一条数据:{}", JSON.toJSONString(user));
            log.info("age:{}", user.getAge());
            //根据自己业务做处理
            doSomething(user);
            dataList.add(user);
        }
    
        private void doSomething(User user) {
            log.info("处理数据!");
        }
    
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            log.info("所有数据解析完成!");
            //datas.clear();
        }
    
        public List<User> getDataList() {
            return dataList;
        }
    
        public void setDataList(List<User> dataList) {
            this.dataList = dataList;
        }
    }
    

    然后,我们定义一个Controller来调用读取上传的Excel

    package com.mrcoder.frameservice.controller;
    import com.alibaba.excel.EasyExcel;
    import com.mrcoder.frameservice.excel.UserModelListener;
    import com.mrcoder.frameservice.model.po.User;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    @RestController
    @RequestMapping("excel")
    public class ExcelController {
    
        private static final Logger logger = LoggerFactory.getLogger(ExcelController.class);
    
        @PostMapping("/importUsers")
        public void importUsers(HttpServletRequest request) throws IOException {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile skuExcel = multipartRequest.getFile("filename");
            InputStream inputStream = skuExcel.getInputStream();
            EasyExcel.read(inputStream, User.class, new UserModelListener()).sheet().doRead();
        }
    

    最后我们postman提交excel文件即可

    excel文件


    image.png

    控制台打印结果


    image.png

    EasyExcel使用问题总结

    @ExcelProperty注解是什么

    这个注解就是Excel文件列对应实体的依据

    @ExcelProperty(index = 1) 
    private String name;
    

    如上代码, 意思就是 User的name值对应Excel内容的第2列值!
    注意, index从0开始, 代表Excel文件的第一列!

    读取excel文件反射成实体后全为NULL

    这个问题,咸鱼君也碰过到, 查阅资料得知,lombok这个依赖和EasyExcel还是有点冲突的, 解决的方法就是
    将实体类上的这两个注解干掉即可, 没碰到此问题的可能是后续版本解决了该bug!

    @Getter
    @Setter
    

    最后, 对EasyExcel使用上还有疑问的可以去官方文档上看~

    https://alibaba-easyexcel.github.io/index.html

    最后,关于EasyExcel反射实体后,进行数据处理的多种方式,可以在我的git项目上找到使用案例, 项目介绍可以看这里.

    https://www.jianshu.com/p/7188dc35d114

    相关文章

      网友评论

        本文标题:37. 从零开始学springboot-集成EasyExcel读

        本文链接:https://www.haomeiwen.com/subject/odvhwhtx.html