zoukankan      html  css  js  c++  java
  • Springboot整合easyExcel导入导出Excel

    背景:

    最近公司有个需求要求可以导入、导出excel,因此在此记录学习一下如何使用Springboot整合easyExcel;
    需求:
    数据库中有张user表,有个业务要求可以导入、导出“用户名单.xls”表

    一、准备:

    创建项目:
    关于springboot项目如何创建这里不再赘述,放一张项目结构图:
    在这里插入图片描述
    1、导入easyexcel、mybatis、mysql依赖

    		<!-- easyexcel相关依赖 -->
    		<dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>1.1.2-beta5</version>
            </dependency>
            <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>
    		<!-- mybatis、mysql相关依赖 -->
    		<dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.1</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.6</version>
            </dependency>

    2、application.yml

    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
    

    3、导出excel

    (1)user实体类
    导出 Excel 时,若需要表头,那么相应的实体类需要继承 BaseRowModel,并加入 @ExcelProperty(value = “id”, index = 0) 注解。其中 value 代表在导出 Excel 时,该字段对应的表头名称;index 代表该字段对应的表头位置(从0开始)。如下图:
    在这里插入图片描述

    //@Data是lombok的一个注解,加上它会自动生成getter、setter方法
    @Data
    public class User extends BaseRowModel {
        @ExcelProperty(value = "ID", index = 0)
        private String id;
        @ExcelProperty(value = "姓名", index = 1)
        private String name;
        @ExcelProperty(value = "年龄", index = 2)
        private Integer age;
    }

    (2)Usercontroller

        @GetMapping("/user/excel")
        public void excelExport(HttpServletResponse response) throws IOException {
            userService.excelExport(response);
        }

    (3)Userservice

    public void excelExport(HttpServletResponse response) throws IOException {
            List<User> list = userDao.queryAllUsers();
            String fileName = "用户名单";
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) + ".xls");
            ServletOutputStream out = response.getOutputStream();
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLS,true);
            Sheet sheet = new Sheet(1,0,User.class);
            //设置自适应宽度
            sheet.setAutoWidth(Boolean.TRUE);
            sheet.setSheetName("用户名单");
            writer.write(list,sheet);
            writer.finish();
            out.flush();
            response.getOutputStream().close();
            out.close();
        }
    

    4、导入excel

    (1)Usercontroller

       @PostMapping("/user/excel")
        public String excelImport(@RequestParam("file")MultipartFile file) throws IOException {
            userService.excelImport(file);
            return "success";
        }
    

    (2)Userservice

    public void excelImport(MultipartFile file) throws IOException {
            if(!file.getOriginalFilename().equals("用户名单.xls") && !file.getOriginalFilename().equals("用户名单.xlsx") ){
                return;
            }
            InputStream inputStream = new BufferedInputStream(file.getInputStream());
            //实例化实现了AnalysisEventListener接口的类
            ExcelListener excelListener = new ExcelListener(userDao);
            ExcelReader reader = new ExcelReader(inputStream,null,excelListener);
            //读取信息
            reader.read(new Sheet(1,1,User.class));
        }

    参考easyExcel官方GitHub demo
    (3)ExcelListener

    public class ExcelListener extends AnalysisEventListener<User> {
        private List<User> datas = new ArrayList<>();
        private static final int BATCH_COUNT = 3000;
        private UserDao userDao;
    
        public ExcelListener(UserDao userDao){
            this.userDao = userDao;
        }
    
        @Override
        public void invoke(User user, AnalysisContext analysisContext) {
            //数据存储到datas,供批量处理,或后续自己业务逻辑处理。
            datas.add(user);
            //达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
            if(datas.size() >= BATCH_COUNT){
                saveData();
                // 存储完成清理datas
                datas.clear();
            }
        }
    
        private void saveData() {
            for(User user : datas){
                userDao.addUser(user);
            }
        }
    
        public List<User> getDatas() {
            return datas;
        }
    
        public void setDatas(List<User> datas) {
            this.datas = datas;
        }
    
        /**
         * 所有数据解析完成了 都会来调用
         */
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            saveData();//确保所有数据都能入库
        }
    }
    

    二、测试

    刚开始的数据库表:
    在这里插入图片描述

    准备一个“用户名单.xls”表,以便待会测试导入功能:
    在这里插入图片描述

    1、 启动项目,使用postman测试“导入”功能:

    在这里插入图片描述
    在这里插入图片描述

    点击send,然后查看数据表:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k7qElnKB-1575975083496)(C:UsersAdministratorAppDataRoamingTypora	ypora-user-imagesimage-20191210181252402.png)]

    上图数据一致,说明导入成功!!!

    2、再用postman测试导出功能:

    在这里插入图片描述

    没有参数,直接send,然后可以看到:

    在这里插入图片描述
    在这里插入图片描述
    将其下载下来查看(本来这里的文件名应该是代码中命名的“用户名单.xls”,但我尝试了很久总是没有变。。。)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X87m7MCo-1575975083497)(C:UsersAdministratorAppDataRoamingTypora	ypora-user-imagesimage-20191210182033780.png)]

    与数据库表数据一致,说明导出成功!

    特别说明:

    这里的excel名字的命名必须是这个,而且里面的主键可以不写,因为可能会遇到主键冲突的问题

  • 相关阅读:
    iOS开发之静态库(二)—— .a
    iOS开发之静态库(一)—— 基本概念
    Linux中ctrl-c, ctrl-z, ctrl-d 区别
    JNI技术基础(1)——从零开始编写JNI代码
    开篇纪念
    java面试题
    jvm系列二之GC收集器
    jvm系列一
    ConcurrentHashMap源码剖析(1.8版本)
    博客系统对比
  • 原文地址:https://www.cnblogs.com/cxy2020/p/13965633.html
Copyright © 2011-2022 走看看