zoukankan      html  css  js  c++  java
  • EasyExcel的用法

    https://www.cnblogs.com/liuyi13535496566/p/12634898.html

    EasyExcel的用法

    一.Excel导入导出的应用场景

    1.数据导入:减轻录入的工作量

    2.数据导出:统计信息归档

    3.数据传输:异构系统之间数据传输

    二。EasyExcel简介

    1.EasyExcel特点

    Java领域解析,生成Excel比较有名的框架有Apache poi,jxl等,但他们都存在一个严重的问题就是非常的耗内存,如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc.

    EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节省内存著称,EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

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

    1.导入maven依赖,主要还需要poi的依赖,并且版本要对应上

    复制代码

    <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>easyexcel</artifactId>
      <version>2.1.1</version>
    </dependency>

    <!--xls-->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.17</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.17</version>
    </dependency>

    复制代码

    2.编写entity对象类

    复制代码
    @Data
    public class DemoData {
        //设置excel表头名称
        @ExcelProperty(value = "学生编号",index = 0)
        private Integer sno;
        @ExcelProperty(value = "学生姓名",index = 1)
        private String sname;
    }
    复制代码

    3.写操作

    复制代码
    public class TestEasyExcelWrite {
    
        public static void main(String[] args) {
    
            //实现excel写的操作
            //1 设置写入文件夹地址和excel文件名称
            String filename = "C:\Users\aus\write.xlsx";
           // 2 调用easyexcel里面的方法实现写操作
           // write方法两个参数:第一个参数文件路径名称,第二个参数实体类class
            EasyExcel.write(filename,DemoData.class).sheet("学生列表").doWrite(getData());
    
        }
    
        //创建方法返回list集合
        private static List<DemoData> getData() {
            List<DemoData> list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                DemoData data = new DemoData();
                data.setSno(i);
                data.setSname("lucy"+i);
                list.add(data);
            }
            return list;
        }
    }
    复制代码

    4.最终效果 

     5.读取excel需要先写一个监听器继承AnalysisEventListener

    复制代码
    public class ExcelListener extends AnalysisEventListener<DemoData> {
        //一行一行读取excel内容
        @Override
        public void invoke(DemoData data, AnalysisContext analysisContext) {
            System.out.println("****"+data);
        }
        //读取表头内容
        @Override
        public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
            System.out.println("表头:"+headMap);
        }
        //读取完成之后
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) { }
    }
    复制代码

    6.读取excel代码

    复制代码
    public class TestEasyExcelRead {
    
        public static void main(String[] args) {
    
            //实现excel读操作
            String filename = "C:\Users\aus\write.xlsx";
            EasyExcel.read(filename,DemoData.class,new ExcelListener()).sheet().doRead();
        }
    }
    复制代码

    打印效果见下图:


    实际项目中开发

    entity

    复制代码
    @Data
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    @ApiModel(value="EduSubject对象", description="课程科目")
    public class EduSubject implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @ApiModelProperty(value = "课程类别ID")
        @TableId(value = "id", type = IdType.ID_WORKER_STR)
        private String id;
    
        @ApiModelProperty(value = "类别名称")
        private String title;
    
        @ApiModelProperty(value = "父ID")
        private String parentId;
    
        @ApiModelProperty(value = "排序字段")
        private Integer sort;
    
        @ApiModelProperty(value = "创建时间")
        @TableField(fill = FieldFill.INSERT)
        private Date gmtCreate;
    
        @ApiModelProperty(value = "更新时间")
        @TableField(fill = FieldFill.INSERT)
        private Date gmtModified;
        
    }
    复制代码
    复制代码
    @Data
    public class SubjectData {
        @ExcelProperty(index = 0)
        private String oneSubjectName;
        @ExcelProperty(index = 1)
        private String twoSubjectName;
    }
    复制代码

    Controller层

    复制代码
    @RestController
    @RequestMapping("/eduservice/subject")
    @CrossOrigin
    public class EduSubjectController {
    
    
        @Autowired
        private EduSubjectService subjectService;
    
        //添加课程分类
        //获取上传过来文件,把文件内容读取出来
        @PostMapping("addSubject")
        public R addSubject(MultipartFile file) {
            //上传过来excel文件
            subjectService.saveSubject(file,subjectService);
            return R.ok();
        }
    
    }
    复制代码

    service层

    复制代码
    @Service
    public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
    
        @Override
        public void saveSubject(MultipartFile file, EduSubjectService subjectService) {
    
            try{
                InputStream in = file.getInputStream();
                EasyExcel.read(in, SubjectData.class,new SubjectExcelListener(subjectService)).sheet().doRead();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    复制代码

     5.监听器继承AnalysisEventListener,这里需要注意的点,因为业务层的SubjectExcelListener 并没有交给Spring容器来管理,所以监听器代码无法注入EduSubjectService ,

    这里通过构造方法的方式传过来,从而完成对数据库的操作。

    复制代码
    public class SubjectExcelListener extends AnalysisEventListener<SubjectData> {
    
        //因为SubjectExcelListener不交给spring进行管理,需要自己new,不能注入其他对象
        //不能实现数据库操作
        public EduSubjectService subjectService;
        public SubjectExcelListener() {}
        public SubjectExcelListener(EduSubjectService subjectService) {
            this.subjectService = subjectService;
        }
    
        //读取excel内容,一行一行进行读取
        @Override
        public void invoke(SubjectData subjectData, AnalysisContext analysisContext) {
            if(subjectData == null) {
                throw new GuliException(20001,"文件数据为空");
            }
    
            //一行一行读取,每次读取有两个值,第一个值一级分类,第二个值二级分类
            //判断一级分类是否重复
            EduSubject existOneSubject = this.existOneSubject(subjectService, subjectData.getOneSubjectName());
            if(existOneSubject == null) { //没有相同一级分类,进行添加
                existOneSubject = new EduSubject();
                existOneSubject.setParentId("0");
                existOneSubject.setTitle(subjectData.getOneSubjectName());//一级分类名称
                subjectService.save(existOneSubject);
            }
    
            //获取一级分类id值
            String pid = existOneSubject.getId();
    
            //添加二级分类
            //判断二级分类是否重复
            EduSubject existTwoSubject = this.existTwoSubject(subjectService, subjectData.getTwoSubjectName(), pid);
            if(existTwoSubject == null) {
                existTwoSubject = new EduSubject();
                existTwoSubject.setParentId(pid);
                existTwoSubject.setTitle(subjectData.getTwoSubjectName());//二级分类名称
                subjectService.save(existTwoSubject);
            }
        }
    
        //判断一级分类不能重复添加
        private EduSubject existOneSubject(EduSubjectService subjectService,String name) {
            QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
            wrapper.eq("title",name);
            wrapper.eq("parent_id","0");
            EduSubject oneSubject = subjectService.getOne(wrapper);
            return oneSubject;
        }
    
        //判断二级分类不能重复添加
        private EduSubject existTwoSubject(EduSubjectService subjectService,String name,String pid) {
            QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
            wrapper.eq("title",name);
            wrapper.eq("parent_id",pid);
            EduSubject twoSubject = subjectService.getOne(wrapper);
            return twoSubject;
        }
    
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
        }
    }
    https://github.com/godmaybelieve
  • 相关阅读:
    Minimum Depth of Binary Tree leetcode java
    Maximum Depth of Binary Tree leetcode java
    Symmetric Tree leetcode java
    Same Tree leetcode java
    Binary Tree Postorder Traversal leetcode java
    Binary Tree Preorder Traversal leetcode java
    Binary Tree Inorder Traversal leetcode java
    Combinations leetcode java
    一键清除Centos iptables 防火墙所有规则
    阿里云centos7.7x64安装open,并配置ip转发和nat伪装
  • 原文地址:https://www.cnblogs.com/yuyu666/p/15034146.html
Copyright © 2011-2022 走看看