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名字的命名必须是这个,而且里面的主键可以不写,因为可能会遇到主键冲突的问题

  • 相关阅读:
    vue中的 computed 和 watch 的区别
    mysql8.0 初始化数据库及表名大小写问题
    sql server alwayson 调整数据文件路径
    zabbix 自定义监控 SQL Server
    mysql 创建用户及授权
    mysql 设置从库只读模式
    mysql8.0 主从复制安装及配置
    centos8.0安装mysql8.0
    centos8替换阿里数据源
    npm publish 报错 【you or one of your dependencies are requesting a package version that is forbidden by your security policy】
  • 原文地址:https://www.cnblogs.com/cxy2020/p/13965633.html
Copyright © 2011-2022 走看看