• Spring Boot 集成 EasyExcel 3.x


    Spring Boot 集成 EasyExcel 3.x

    Spring Boot 集成 EasyExcel 3.x

    本章节将介绍 Spring Boot 集成 EasyExcel(优雅实现Excel导入导出)。

    🤖 Spring Boot 2.x 实践案例(代码仓库)

    介绍

    EasyExcel 是一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具。它能让你在不用考虑性能、内存的等因素的情况下,快速完成 Excel 的读、写等功能。

    EasyExcel文档地址:https://easyexcel.opensource.alibaba.com/

    快速开始

    引入依赖
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>easyexcelartifactId>
        <version>3.1.3version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    简单导出

    以导出用户信息为例,接下来手把手教大家如何使用EasyExcel实现导出功能!

    定义实体类

    在EasyExcel中,以面向对象思想来实现导入导出,无论是导入数据还是导出数据都可以想象成具体某个对象的集合,所以为了实现导出用户信息功能,首先创建一个用户对象User实体类,用于封装用户信息:

    package com.bailuo.entity;
    
    import com.alibaba.excel.annotation.ExcelIgnore;
    import com.alibaba.excel.annotation.ExcelProperty;
    import com.alibaba.excel.annotation.write.style.ColumnWidth;
    import com.alibaba.excel.converters.Converter;
    import com.bailuo.utils.GenderConverter;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
    
        @ExcelIgnore
        private long id;
        @ExcelProperty("登录名")
        @ColumnWidth(20)
        private String loginName;
        @ExcelProperty("用户名")
        @ColumnWidth(20)
        private String userName;
        @ExcelProperty("密码")
        @ColumnWidth(20)
        private String password;
        @ExcelProperty(value = "性别",converter = GenderConverter.class)
        @ColumnWidth(20)
        private Integer sex;
        @ExcelProperty("身份证号")
        @ColumnWidth(30)
        private String identityCode;
        @ExcelProperty("邮箱")
        @ColumnWidth(30)
        private String email;
        @ExcelProperty("手机号")
        @ColumnWidth(30)
        private String mobile;
        @ExcelProperty("状态")
        private long type;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    上面代码中类属性上使用了EasyExcel核心注解:

    • @ExcelProperty:核心注解,value属性可用来设置表头名称,converter属性可以用来设置类型转换器;
    • @ColumnWidth:用于设置表格列的宽度;
    • @DateTimeFormat:用于设置日期转换格式;
    • @NumberFormat:用于设置数字转换格式。
    自定义转换器

    在EasyExcel中,如果想实现枚举类型到字符串类型转换(例如gender属性:1 -> 男2 -> 女),需实现Converter接口来自定义转换器,下面为自定义GenderConverter性别转换器代码实现:

    /**
     * Excel 性别转换器
     *
     * @author william@StarImmortal
     */
    public class GenderConverter implements Converter<Integer> {
        @Override
        public Class<?> supportJavaTypeKey() {
            return Integer.class;
        }
    
        @Override
        public CellDataTypeEnum supportExcelTypeKey() {
            return CellDataTypeEnum.STRING;
        }
    
        @Override
        public Integer convertToJavaData(ReadConverterContext<?> context) {
            return GenderEnum.convert(context.getReadCellData().getStringValue()).getValue();
        }
    
        @Override
        public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) {
            return new WriteCellData<>(GenderEnum.convert(context.getValue()).getDescription());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    /**
     * 性别枚举
     *
     * @author william@StarImmortal
     */
    @Getter
    @AllArgsConstructor
    public enum GenderEnum {
    
        /**
         * 未知
         */
        UNKNOWN(0, "未知"),
    
        /**
         * 男性
         */
        MALE(1, "男性"),
    
        /**
         * 女性
         */
        FEMALE(2, "女性");
    
        private final Integer value;
    
        @JsonFormat
        private final String description;
    
        public static GenderEnum convert(Integer value) {
            return Stream.of(values())
                    .filter(bean -> bean.value.equals(value))
                    .findAny()
                    .orElse(UNKNOWN);
        }
    
        public static GenderEnum convert(String description) {
            return Stream.of(values())
                    .filter(bean -> bean.description.equals(description))
                    .findAny()
                    .orElse(UNKNOWN);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    定义接口
    package com.bailuo.controller;
    
    import com.alibaba.excel.EasyExcel;
    import com.alibaba.excel.support.ExcelTypeEnum;
    import com.bailuo.entity.User;
    import com.bailuo.service.UserService;
    import com.bailuo.vo.ResultData;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.lang.reflect.Member;
    import java.lang.reflect.Method;
    import java.net.URLEncoder;
    import java.security.ProtectionDomain;
    import java.util.List;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        UserService userService;
    
        @GetMapping("/export")
        public void exportUserExcel(HttpServletResponse response) {
            try {
    //            Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class, ProtectionDomain.class);
    //            defineClassMethod.setAccessible(true);
                this.setExcelResponseProp(response, "用户列表");
                List<User> userList = userService.selectUserList();
                for (User user : userList) {
                    System.out.println(user);
                }
                EasyExcel.write(response.getOutputStream())
                        .head(User.class)
                        .excelType(ExcelTypeEnum.XLSX)
                        .sheet("用户列表")
                        .doWrite(userList);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 设置响应结果
         *
         * @param response    响应结果对象
         * @param rawFileName 文件名
         * @throws UnsupportedEncodingException 不支持编码异常
         */
        private void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("a", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        }
    
        /**
         * 读取用户列表数据
         *
         * @return 用户列表数据
         * @throws IOException IO异常
         */
        private List<User> getUserList() throws IOException {
            ObjectMapper objectMapper = new ObjectMapper();
            ClassPathResource classPathResource = new ClassPathResource("mock/users.json");
            InputStream inputStream = classPathResource.getInputStream();
            return objectMapper.readValue(inputStream, new TypeReference<List<User>>() {
            });
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    测试接口

    运行项目,通过 Postman 或者 Apifox 工具来进行接口测试

    注意:在 Apifox 中访问接口后无法直接下载,需要点击返回结果中的下载图标才行,点击之后方可对Excel文件进行保存。

    接口地址:http://localhost:8080/user/export

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    在这里插入图片描述

    导入

    以导入用户信息为例,接下来手把手教大家如何使用EasyExcel实现导入功能!

    package com.bailuo.controller;
    
    import com.alibaba.excel.EasyExcel;
    import com.bailuo.entity.User;
    import com.bailuo.service.UserService;
    import com.bailuo.vo.ResultData;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.IOException;
    import java.util.List;
    
    @RestController
    @RequestMapping("/excel")
    public class ExcelController {
        @Autowired
        UserService userService;
        @PostMapping("/import/user")
        @ResponseBody
        public ResultData importUserExcel(@RequestPart(value = "file") MultipartFile file) {
            if(file==null){
                System.out.println("空空空");
            }else{
                System.out.println("不空");
            }
            try {
                List<User> userList = EasyExcel.read(file.getInputStream())
                        .head(User.class)
                        .sheet()
                        .doReadSync();
                System.out.println(userList);
                userService.insertUser(userList);
                System.out.println("userList:"+userList);
                return ResultData.success(userList);
            } catch (IOException e) {
                System.out.println("异常异常异常");
                return null;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述

  • 相关阅读:
    Docker-harbor私有仓库部署与管理
    扩散模型学习
    670.最大交换 暴力、单调栈、指针的逆序遍历 三种解题思路。
    老鼠走迷宫java ---递归
    华为、小米OV折叠屏市场再厮杀
    解决项目下的lib包没有打进jar的问题
    4.1提出问题&4.2拉格朗日插值
    代码越写越乱?那是因为你没用责任链
    MLIR编译框架的使用与探索
    【第八章 索引,索引结构,B-Tree,B+Tree,Hash,索引分类,聚集索引&二级索引,索引语法】
  • 原文地址:https://blog.csdn.net/m0_72166275/article/details/138144212