zoukankan      html  css  js  c++  java
  • springboot实现EasyExcel对Excel读和写操作

    GitHub地址参照:https://github.com/alibaba/easyexcel

    写操作(将数据写入到excel文件)

    1.引入依赖

    <dependencies>
        <!-- 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>
    </dependencies>

    2.创建实体类,这里用的lombok生成get和set。

    package com.stu.codeGenerator.excel;
    
    import com.alibaba.excel.annotation.ExcelProperty;
    import lombok.Data;
    
    @Data
    public class DemoDataExcel {
    
        //设置Excel表头名称
    
        @ExcelProperty("学生编号")
        private Integer sno;
    
        @ExcelProperty("学生姓名")
        private String sname;
    
    }

    3.测试方法(两种方式都可以)

    方法1

    package com.stu.codeGenerator.excel;
    
    import com.alibaba.excel.EasyExcel;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class DemoEasyExcel {
    
        public static void main(String[] args) {
    //写法1
    //实现excel写的操作(生成一个excel文件,并且有内容) //1.设置写入文件地址和excel文件名称,如果路径是C盘可能会报错。 String fileName = "F:\write.xlsx"; //2.调用easyexcel里面的方法实现写操作 //write有两个参数,第一个参数是文件路径名称,第二个参数是实体类class,doWrite里需要传递一个集合 EasyExcel.write(fileName,DemoDataExcel.class).sheet("学生列表").doWrite(getData()); } private static List<DemoDataExcel> getData(){ List<DemoDataExcel> list = new ArrayList<>(); for(int i = 0;i<10;i++){ DemoDataExcel data = new DemoDataExcel(); data.setSno(i); data.setSname("Excel"+i); list.add(data); } return list; } }

    方法2

    public static void main(String[] args) throws Exception {
        // 写法2,方法二需要手动关闭流
        String fileName = "F:\112.xlsx";
        // 这里 需要指定写用哪个class去写
        ExcelWriter excelWriter = EasyExcel.write(fileName, DemoDataExcel.class).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("写入方法二").build();
        excelWriter.write(data(), writeSheet);
        /// 千万别忘记finish关闭流
        excelWriter.finish();
    }

    4.执行main方法,excel效果如下。

    读操作基本示例(从excel文件把数据读出来)

    1.创建实体类(注解多了一个value和index)

    package com.stu.codeGenerator.excel;
    
    import com.alibaba.excel.annotation.ExcelProperty;
    import lombok.Data;
    
    @Data
    public class DemoDataExcel {
    
        //设置Excel表头名称
    
        //0表示第一列
        @ExcelProperty(value = "学生编号",index = 0)
        private Integer sno;
    
        //1表示第二列
        @ExcelProperty(value = "学生姓名",index = 1)
        private String sname;
    
    }

    2.创建一个监听器类继承AnalysisEventListener,进行excel文件读取,他是一行一行的读取

    package com.stu.codeGenerator.excel;
    
    import com.alibaba.excel.context.AnalysisContext;
    import com.alibaba.excel.event.AnalysisEventListener;
    
    import java.sql.SQLOutput;
    import java.util.Map;
    
    public class ExcelListener extends AnalysisEventListener<DemoDataExcel> {
    
        //一行一行读取excel内容,第一行表头不会读取
        @Override
        public void invoke(DemoDataExcel demoDataExcel, AnalysisContext analysisContext) {
    
            System.out.println("++++行内容++++="+demoDataExcel);
        }
    
        //读取表头内容
        @Override
        public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
            System.out.println("+++表头+++++="+headMap);
        }
    
        //读取完成之后
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("++++++++="+analysisContext);
    
        }
    
    }

    3.测试方法(两个方法)

    方法1

    package com.stu.codeGenerator.excel;
    
    import com.alibaba.excel.EasyExcel;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class DemoEasyExcel {
    
        public static void main(String[] args) {
    //        //实现excel写的操作(生成一个excel文件,并且有内容)
    //        //1.设置写入文件地址和excel文件名称
    //        String fileName = "F:\write.xlsx";
    //
    //        //2.调用easyexcel里面的方法实现写操作
    //        //write有两个参数,第一个参数是文件路径名称,第二个参数是实体类class
    //        EasyExcel.write(fileName,DemoDataExcel.class).sheet("学生列表").doWrite(getData());
            String fileName = "F:\write.xlsx";
            EasyExcel.read(fileName,DemoDataExcel.class,new ExcelListener()).sheet().doRead();
    
        }
    
        private static List<DemoDataExcel> getData(){
            List<DemoDataExcel> list = new ArrayList<>();
            for(int i = 0;i<10;i++){
                DemoDataExcel data = new DemoDataExcel();
                data.setSno(i);
                data.setSname("Excel"+i);
                list.add(data);
            }
            return list;
        }
    }

    方法2

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

    控制台输出:

    +++表头+++++={0=学生编号, 1=学生姓名}
    ++++行内容++++=DemoDataExcel(sno=0, sname=Excel0)
    ++++行内容++++=DemoDataExcel(sno=1, sname=Excel1)
    ++++行内容++++=DemoDataExcel(sno=2, sname=Excel2)
    ++++行内容++++=DemoDataExcel(sno=3, sname=Excel3)
    ++++行内容++++=DemoDataExcel(sno=4, sname=Excel4)
    ++++行内容++++=DemoDataExcel(sno=5, sname=Excel5)
    ++++行内容++++=DemoDataExcel(sno=6, sname=Excel6)
    ++++行内容++++=DemoDataExcel(sno=7, sname=Excel7)
    ++++行内容++++=DemoDataExcel(sno=8, sname=Excel8)
    ++++行内容++++=DemoDataExcel(sno=9, sname=Excel9)
    ++++++++=com.alibaba.excel.context.AnalysisContextImpl@491666ad
    
    Process finished with exit code 0

    读操作--保存到数据示例(从excel文件把数据读出来,保存到数据库)

    SubJectData实体类封装

    package com.stu.eduservice.entity.excel;
    
    import com.alibaba.excel.annotation.ExcelProperty;
    import lombok.Data;
    
    @Data
    public class SubJectData {
    
        @ExcelProperty(index = 0)
        private String oneSubjectName;
    
        @ExcelProperty(index = 1)
        private String twoSubjectName;
    } 

    controller层

    package com.stu.eduservice.controller;
    
    import com.stu.commonutils.ResultData;
    import com.stu.eduservice.entity.EduSubject;
    import com.stu.eduservice.entity.subject.Subject;
    import com.stu.eduservice.service.IEduSubjectService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import org.springframework.web.multipart.MultipartFile;
    
    import java.util.List;
    
    /**
     * <p>
     * 课程科目 前端控制器
     * </p>
     *
     * @author stu
     * @since 2021-05-24
     */
    @RestController
    @RequestMapping("/eduservice/subject")
    @CrossOrigin
    public class EduSubjectController {
    
        @Autowired
        private IEduSubjectService eduSubjectService;
    
        //添加课程分类
        //获取上传的excel文件,把文件的内容读取出来
        @PostMapping("addSubJect")
        public ResultData addSubJect(MultipartFile file){
            //上传过来的excel文件
    
            eduSubjectService.addSubJect(file,eduSubjectService);
            return ResultData.success();
        }
    
        //课程分类列表(树形)
        @GetMapping("getAllSubJect")
        public ResultData getAllSubJect(){
            List<Subject> list = eduSubjectService.getAllSubJect();
            return ResultData.success().data("list",list);
        }
    
    
    }

    service接口

    package com.stu.eduservice.service;
    
    import com.stu.eduservice.entity.EduSubject;
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.stu.eduservice.entity.subject.Subject;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.util.List;
    
    /**
     * <p>
     * 课程科目 服务类
     * </p>
     *
     * @author stu
     * @since 2021-05-24
     */
    public interface IEduSubjectService extends IService<EduSubject> {
    
        void addSubJect(MultipartFile file,IEduSubjectService eduSubjectService);
    
        List<Subject> getAllSubJect();
    }

    service实现类

    package com.stu.eduservice.service.impl;
    
    import com.alibaba.excel.EasyExcel;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.stu.eduservice.entity.EduSubject;
    import com.stu.eduservice.entity.excel.SubJectData;
    import com.stu.eduservice.entity.subject.Subject;
    import com.stu.eduservice.listener.SubJectExcelListener;
    import com.stu.eduservice.mapper.EduSubjectMapper;
    import com.stu.eduservice.service.IEduSubjectService;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import org.springframework.beans.BeanUtils;
    import org.springframework.stereotype.Service;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * <p>
     * 课程科目 服务实现类
     * </p>
     *
     * @author stu
     * @since 2021-05-24
     */
    @Service
    public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements IEduSubjectService {
    
        @Override
        public void addSubJect(MultipartFile file,IEduSubjectService eduSubjectService) {
    
            try {
                //文件输入流
                InputStream in = file.getInputStream();
                //调用读方法,通过监听类把数据保存到数据库
                EasyExcel.read(in, SubJectData.class,new SubJectExcelListener(eduSubjectService)).sheet().doRead();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    
        @Override
        public List<Subject> getAllSubJect() {
            List<Subject> root = new ArrayList<Subject>();
    
            QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
            List<EduSubject> permissionList = baseMapper.selectList(wrapper);//根菜单
    
            List<Subject> subjectList = new ArrayList<>();
    
            Map<String,Subject> map = new HashMap<String,Subject>();
            for(EduSubject bean :permissionList){
                Subject subject = new Subject();
                BeanUtils.copyProperties(bean,subject);
                map.put(bean.getId(), subject);
                subjectList.add(subject);
            }
            for(Subject bean :subjectList){
                Subject children = bean;
                if(bean.getParentId().equals("0")){
                    root.add(bean);
                }else{
                    Subject parent = map.get(children.getParentId());
                    parent.getChildren().add(children);
                }
            }
            return root;
        }
    } 

    监听类继承AnalysisEventListener,通过invoke方法把数据保存到数据库

    package com.stu.eduservice.listener;
    
    import com.alibaba.excel.context.AnalysisContext;
    import com.alibaba.excel.event.AnalysisEventListener;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.stu.eduservice.entity.EduSubject;
    import com.stu.eduservice.entity.excel.SubJectData;
    import com.stu.eduservice.service.IEduSubjectService;
    import com.stu.servicebase.exceptionHandler.GuliException;
    
    public class SubJectExcelListener extends AnalysisEventListener<SubJectData> {
    
        //因为SubJectExcelListener不能交给spring进行管理,需要自己new,不能注入其他对象
        //不能实现数据库操作 new mapper
    
        public IEduSubjectService eduSubjectService;
    
        //让对象可以使用start,创建一个有参构造和一个无参构造
        public SubJectExcelListener(){}
        public SubJectExcelListener(IEduSubjectService eduSubjectService){
            this.eduSubjectService = eduSubjectService;
        }
        //让对象可以使用end
    
        @Override
        public void invoke(SubJectData subJectData, AnalysisContext analysisContext) {
            if(subJectData == null ){
                throw new GuliException(20001,"数据为空");
            }
            //一行一行读取,每次读取有两个值,一级分类和二级分类
            EduSubject eduSubjectOne =this.checkOne(eduSubjectService,subJectData.getOneSubjectName());
            if(eduSubjectOne == null ){
    
                eduSubjectOne = new EduSubject();
                eduSubjectOne.setParentId("0");
                eduSubjectOne.setTitle(subJectData.getOneSubjectName());
    
                eduSubjectService.save(eduSubjectOne);
            }
    
            //取得一级分类的id,作为二级分类的父id,pid
            String pid = eduSubjectOne.getId();
            EduSubject eduSubjectTwo =this.checkTwo(eduSubjectService,subJectData.getTwoSubjectName(),pid);
    
            if(eduSubjectTwo == null ){
                eduSubjectTwo = new EduSubject();
                eduSubjectTwo.setParentId(pid);
                eduSubjectTwo.setTitle(subJectData.getTwoSubjectName());
    
                eduSubjectService.save(eduSubjectTwo);
            }
        }
    
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
        }
        //判断一级分类不能重复
        private EduSubject checkOne(IEduSubjectService eduSubjectService,String name){
            QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
            wrapper.eq("title",name);
            wrapper.eq("parent_id",0);
            EduSubject eduSubject = eduSubjectService.getOne(wrapper);
            return eduSubject;
        }
    
        //判断二级分类不能重复
        private EduSubject checkTwo(IEduSubjectService eduSubjectService,String name,String pid){
            QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
            wrapper.eq("title",name);
            wrapper.eq("parent_id",pid);
            EduSubject eduSubject = eduSubjectService.getOne(wrapper);
            return eduSubject;
        }
    
    
    }
  • 相关阅读:
    2019-2020-1 20175228 实验四 外设驱动程序设计
    2019-2020-1 20175228 实验三 实时系统
    2019-2020-1-20175332 20175323 20175228 实验一开发环境的熟悉
    2018-2019-2 20175228实验五《Java网络编程》实验报告
    2018-2019-2 20175228实验四《Android开发基础》实验报告
    2018-2019-2 20175228实验三《敏捷开发与XP实践》实验报告
    MyCP
    2018-2019-2 20175228实验二《面向对象程序设计》实验报告
    2018-2019-2 20175228实验一《Java开发环境的熟悉》实验报告
    转()析构函数
  • 原文地址:https://www.cnblogs.com/konglxblog/p/14806592.html
Copyright © 2011-2022 走看看