Spring Boot 集成 EasyExcel 3.x

发布于:2024-04-28 ⋅ 阅读:(23) ⋅ 点赞:(0)

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.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.3</version>
</dependency>
简单导出

以导出用户信息为例,接下来手把手教大家如何使用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;
}

上面代码中类属性上使用了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());
    }
}
/**
 * 性别枚举
 *
 * @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);
    }
}
定义接口
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>>() {
        });
    }
}

测试接口

运行项目,通过 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;
        }
    }
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到