• EasyExcel基本使用


    EasyExcel:

    1、EasyExcel特点

    Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或 者JVM频繁的full gc。EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

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

    导入依赖:

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

    2、添加课程分类功能

    • 1.使用EasyExcel读取excel内容添加数据
    使用easyExcel导出案例:

    entity:

    //设置表头和添加的数据字段
    @ToString
    @Data
    public class DemoData {
        //设置表头名称
        @ExcelProperty("学生编号")
        private int sno;
    
        //设置表头名称
        @ExcelProperty("学生姓名")
        private String sname;
    
    }
    

    导出数据方法一:

        public static void main(String[] args) {
            inputDateEasyExcel1();
        }
    
        /**
         * 数据
         *
         * @return
         */
        private static List<DemoData> testData() {
            //循环设置要添加的数据,最终封装到list集合中
            ArrayList<DemoData> list = new ArrayList<>();
            for (int i = 1; i < 20; i++) {
                DemoData demoData = new DemoData();
                demoData.setSno(i);
                demoData.setSname("金融" + i + "号");
    
                list.add(demoData);
            }
            return list;
        }
    
        /**
         * EasyExcel实现写操作方法一
         */
        public static void inputDateEasyExcel1() {
            //写入文件路径
            String fileName = "E:\project\1.xlsx";
    /**
     * 这里 需要指定写用哪个class去写,
     * 然后写到第一个sheet,名字为模板 然后文件流会自动关闭
     * testData()数据方法
     */
            EasyExcel.write(fileName, DemoData.class).sheet().doWrite(testData());
        }
    

    导出数据方法二:

        /**
         * EasyExcel实现导出方法二
         */
        public static void inputDateEasyExcel2() {
            //写法二:
            String fileName = "E:\project\2.xlsx";
            //这里需要指定写用那个class去写
            ExcelWriter writerBuilder = EasyExcel.write(fileName, DemoData.class).build();
    
            WriteSheet writeSheet = EasyExcel.writerSheet("导出写法二").build();
            writerBuilder.write(testData(), writeSheet);
    
            // 千万别忘记finish否则硬盘奔溃 会帮忙关闭流
            writerBuilder.finish();
    
        }
    
    使用easyExcel导入案例:
     * 通过EasyExcel导入实体类
    
    @Data
    @ToString
    public class ReadData {
    
        //设置列对应的属性
        @ExcelProperty(index = 0)
        private int sid;
    
        //设置列对应的属性
        @ExcelProperty(index = 1)
        private String sname;
    }
    

    2、创建读取操作的监听器

    //创建读取excel监听器
    public class ExcelListener extends AnalysisEventListener<ReadData> {
    
        //创建list集合封装最终的数据
        List<ReadData> list= new ArrayList<>();
    
        //一行一行去读取excle内容
        @Override
        public void invoke(ReadData readData, AnalysisContext analysisContext) {
            System.out.println("==="+readData);
            //数据放进list集合中
            list.add(readData);
        }
    
        //读取excel表头信息
        @Override
        public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
            super.invokeHeadMap(headMap, context);
            System.out.println("表头信息:"+headMap);
        }
    
        //读取完成后最后执行
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
        }
    }
    

    3.调用实现最终的读取

    public class EasyExcelInputTest {
        public static void main(String[] args) throws FileNotFoundException {
           //写法一:
            String fileName = "E:\project\2.xlsx";
       //这里需要指定读那个class去读取,读到第一个sheet文件流会自动关闭
            EasyExcel.read(fileName, ReadData.class,
                    new ExcelListener()).sheet().doRead();;
             // 写法2:
            InputStream in = new BufferedInputStream(new FileInputStream("E:\project\1.xlsx"));
             ExcelReader excelReader = EasyExcel.read(in, ReadData.class, new
                    ExcelListener()).build();
             ReadSheet readSheet = EasyExcel.readSheet(0).build();
             excelReader.read(readSheet);
             // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
             excelReader.finish();
        }
    
    }
    

    升级版监听器:校验

    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) {
    
        }
    }
    
  • 相关阅读:
    Java 零基础跑起第一个程序
    Xcode6 引入第三方静态库project的方法
    Cocos2d-x3.0 RenderTexture(三)
    POJ 题目3461 Oulipo(KMP)
    unity3D游戏开发实战原创视频讲座系列9之塔防类游戏开发第一季
    android 虚拟按键是通过哪种机制上报的?
    深入理解 C 指针阅读笔记 -- 第五章
    【1】按照Django官网,编写一个web app 创建project/配置数据库
    [Swift]LeetCode442. 数组中重复的数据 | Find All Duplicates in an Array
    [Swift]LeetCode441. 排列硬币 | Arranging Coins
  • 原文地址:https://www.cnblogs.com/jinronga/p/14467154.html
Copyright © 2020-2023  润新知