⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 zzuhkp.blog.csdn.net/article/details/125097026 「大鹏cool」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

原来

Excel 与导出是项目中的一个功能很容易导入中的 Excel,由于 Java 导出。 poi,在高处常用导入与运行 OOM 或完全使用 Excel,基于 Easy项目。

简化计算功能,轻松将Excel与解决对象简化了一个API映射Excel之间的简单关系,几行代码除了实现复杂的导入功能,通过导入了。

EasyExcel 问题

一切都是美好的,不过经常把Excel导入与发布的发现,一样的Excel还是没有完美的。

首先,导入与导出的 Excel 本质是将 Excel 文件内容与 Java 对象之间做一个功能映射,轻松将 Excel 的只是在这之间多转换。如果项目中的 Excel 导入与导出比较,会大量的样板式代码,使用体验类似于 JDBC。

另外,还会附带另外一种校验功能,这是 Easy Excel 不支持的功能。

而目前的 spring boot 已经成为必备的 Java 开发框架,excel 也没有进行整合。

分析与解决

导入内容和导出方法通常会发生在 Web 环境中,对于 Spring MVC 来说,可以将请求信息转换为各种类型的控制器方法参数,将控制器返回值作为客户端支持的。

如果使用自定义板的控制器参数接收 Excel 文件内容,将方法控制器的方法返回值转换为 Excel 文件,可以直接从 Excel 导入与导出时的样式代码。

另外在将转换为控制器方法参数时还可以加入自定义请求的逻辑。

Excel 与外接样板代码、看问题的业务逻辑,这里可以单独拿出来,我在 EasyExcel 的基础上板式项目中封装了一个 easyexcel-spring-booter 的项目,导入了 EasyExcel 上手的尺寸窗帘,对用户而言只需要使用 EasyExcel 定义的注解提供映射关系就可以了,适用于场景的简单导入关系。

项目代码已上传:

https://github.com/zzuhkp/easyexcel-spring-boot-starter

下面就来看看如何使用吧。

Spring Boot Excel 导入与导出

引入依

首先需要依赖,坐标如下。

<dependency>
<groupId>com.zzuhkp</groupId>
<artifactId>easyexcel-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

很可能是当前项目的物品传输中央,需要的小伙伴可以自行上传到仓库或直接把代码嵌入自己的仓库。

Excel导入

首先看下要导入的Excel内容吧。

为了接收 Excel 文件内容,我们需要定义一个 Model 类。

@Data
public class DemoData {

@ExcelProperty(index = 0)
private Integer integer;

@ExcelProperty(index = 1)
private String string;

@ExcelProperty(index = 2)
private Date date;
}

导入基本功能

然后使用List<T>参数接收。

@PostMapping("/list/obj")
public List<DemoData> listObj(@ExcelParam List<DemoData> list) {
return list;
}

注意参数前添加了@ExcelParam注解,使用标识Excel文件参数。这样,一个导入实现功能了,是不是很简单呢?

下接收名称为文件的格式不作为 Excel 文件修改,如果满足还可以默认。

@ExcelParam(value = "file", required = true)

进阶导入功能

例如,Excel 这个对象可能是我们比较有趣的对象的元数据,Excel 是第几行记录产生的,这个对象的字段几列,这时我们可以使用ReadRows<T>接收。

@PostMapping("/list/rows")
public ReadRows<DemoData> readRows(@ExcelParam ReadRows<DemoData> readRows) {
return readRows;
}

ReadRows 使用两个字段记录行映射关系与列映射关系。

public class ReadRows<T> {

private ExcelReadHeadProperty excelReadHeadProperty;

private List<ReadRow<T>> rows;
}

ExcelReadHeadProperty是Excel自带的类,列映射关系的元数据。ReadRow是自定义的类,表示Easy行映射关系的元数据。

看下ReadRow定义吧。

public class ReadRow<T> {

// 行索引,从 0 开始
private final Integer rowIndex;

// 行记录对应对象
private final T data;
}

使用ExcelReadHeadProperty获取字段的索引列的示例。

// 对象字段名称 -> 从 0 开始的列索引
Map<String, Integer> fieldColumnIndexMap = readRows.getExcelReadHeadProperty().getHeadMap().values()
.stream().collect(Collectors.toMap(Head::getFieldName, Head::getColumnIndex));

Excel 导出

这里对Excel的导出进行了简单的支持。将List<T>定义为controller方法返回值认知。

@ExcelResponse
@GetMapping("/list/download")
public List<DemoData> downloadList() {
return Arrays.asList(new DemoData(1, "hello", new Date()), new DemoData(2, "excel", new Date()));
}

需要注意的是使用@ExcelResponse注解表示响应内容为 Excel 文件。默认情况下,下载的文件名称为default.xlxs,写入名称为 Sheet1 的工作表中。如果不满足需求可以修改。

@ExcelResponse(fileName = "测试文件", sheetName = "工作表1")

Excel导入参数校验

的参数是滑Excel的导入功能,在这里进行了常用的支持,使用如荔枝般顺顺的弹簧靴。

恰巧

与spring boot解使用方式一样,将@Validated@Valid注添加到@ExcelParam参数上即可。

@PostMapping("/list/obj")
public List<DemoData> listObj(@ExcelParam @Validated List<DemoData> list) {
return list;
}

智能规则定义

Bean Validation 定义验证规则

下框架使用JSR-303 Bean Validation规范定义的校验可解校验,需要手动情况spring-boot-starter-validation,通过设置环境变量默认值easyexcel.validator.default.enable=false

@Data
public class DemoData {

@NotNull(message = "参数不能为空")
private Integer integer;

private String string;

private Date date;
}

还可以自定义另外对对象表示感谢。

... 省略其他元注解
@Constraint(validatedBy = {DemoDataValid.DemoDataValidator.class})
public @interface DemoDataValid {
... 省略注解属性

class DemoDataValidator implements ConstraintValidator<DemoDataValid, DemoData> {

@Override
public boolean isValid(DemoData value, ConstraintValidatorContext context) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("测试对象校验").addConstraintViolation();
return false;
}
}

}
@DemoDataValid
public class DemoData {
... 省略属性
}

ExcelValidator 接口定义校验规则

Bean Validation注解只能定义为对某个对象或对象,如果需要所有的对象进行验证,然后可以实现框架定义的ExcelValidator接口,将实现 Bean。

这个接口定义如下。

public interface ExcelValidator<T> {

ExcelValidErrors validate(ReadRows<T> readRows);
}

ExcelValidErrors接收确认的错误信息,分别用于使用接口ExcelValidObjectErrorExcelValidFieldError接口定义行错误信息和单元格错误信息。

public class ExcelValidErrors {
// 行错误信息或单元格错误信息列表
private final List<ExcelValidObjectError> errors;
}

public interface ExcelValidObjectError {

// 获取行号,从 1 开始
Integer getRow();

// 获取错误消息
String getMessage();
}

public interface ExcelValidFieldError extends ExcelValidObjectError {

// 获取列,从 1 开始
Integer getColumn();
}

例如,如果需要对所有的 DemoData 替换整数字段的值不能重复,可以使用替换的代码。

@Component
public class CustomExcelValidator implements ExcelValidator<DemoData> {
@Override
public ExcelValidErrors validate(ReadRows<DemoData> readRows) {
ExcelValidErrors errors = new ExcelValidErrors();

Map<Integer, List<ReadRow<DemoData>>> group = readRows.getRows().stream()
.collect(Collectors.groupingBy(item -> item.getData().getInteger()));

for (Map.Entry<Integer, List<ReadRow<DemoData>>> entry : group.entrySet()) {
if (entry.getValue().size() > 1) {
for (ReadRow<DemoData> readRow : entry.getValue()) {
errors.addError(new DefaultExcelObjectError(readRow.getRowIndex() + 1, "参数重复"));
}
}
}
return errors;
}
}

校验结果接收

与 Spring MVC 类似设计,这里也提供了接收会话结果的方式。

异常智能手机结果

开启异常方式后,如果信息通知结果中包含错误,错误信息封装ExcelValidException,可以通过异常异常和异常收集。

@RestControllerAdvice
public class GlobalExceptionControllerAdvice {

@ExceptionHandler(ExcelValidException.class)
public String handleException(ExcelValidException e) {
ExcelValidErrors errors = e.getErrors();
return JSON.toJSONString(errors);
}
}

控制器方法参数验证结果

如果不想通过异常信息的方式接收到错误的信息,还可以将其添加到@ExcelParam参数的背面,示例代码如下。

@PostMapping("/list/obj")
public List<DemoData> listObj(@ExcelParam @Validated List<DemoData> list, ExcelValidErrors errors) {
if (errors.hasErrors()) {
String messages = errors.getAllErrors().stream().map(ExcelValidObjectError::getMessage).collect(Collectors.joining(" | "));
throw new RuntimeException("发现异常:" + messages);
}
return list;
}

总结

easyexcel-spring-boot-starter应用了前面文章的各种 Spring 知识量并不大,对具体的小伙伴可以自行统一代码。由于这个框架把 Excel 中的所有数据收集到内存中,因此比较适合一些比较简单的场景。

文章目录
  1. 1. 原来
  2. 2. EasyExcel 问题
  3. 3. 分析与解决
  4. 4. Spring Boot Excel 导入与导出
    1. 4.1. 引入依
    2. 4.2. Excel导入
      1. 4.2.1. 导入基本功能
      2. 4.2.2. 进阶导入功能
    3. 4.3. Excel 导出
    4. 4.4. Excel导入参数校验
      1. 4.4.1. 恰巧
      2. 4.4.2. 智能规则定义
        1. 4.4.2.1. Bean Validation 定义验证规则
      3. 4.4.3. ExcelValidator 接口定义校验规则
      4. 4.4.4. 校验结果接收
      5. 4.4.5. 异常智能手机结果
      6. 4.4.6. 控制器方法参数验证结果
  5. 5. 总结