本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
Spring Boot 集成 EasyExcel 3.x
Spring Boot 集成 EasyExcel 3.x
本章节将介绍 Spring Boot 集成 EasyExcel(优雅实现 Excel 导入导出)。
介绍
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;
}
}
}
