当前位置: 首页 > news >正文

EasyExcel动态映射Excel数据到任意实体类教程

在使用EasyExcel进行Excel导入时,我们经常需要将Excel中的数据映射到Java实体类中。如果Excel的列名是固定的,我们可以通过@ExcelProperty("列名")注解直接在实体类中指定列名。但如果Excel的列名不固定,或者我们希望根据Excel的第一行来动态确定映射关系,我们就需要一种更灵活的方法。本教程将介绍如何使用EasyExcel创建一个工具类,以支持动态映射Excel数据到任意实体类。

步骤1:添加EasyExcel依赖

首先,确保你的项目中已经添加了EasyExcel的依赖。如果使用Maven,可以在pom.xml中添加如下依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.x.x</version> <!-- 使用最新版本 -->
</dependency>

步骤2:创建动态映射工具类

创建一个工具类DynamicExcelUtil,它将负责读取Excel文件,并根据第一行的列名动态映射数据到实体类。

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import lombok.var;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;public class ExcelUtil {/*** 读取 Excel 文件并返回数据模型列表。** @param fileName Excel 文件的路径。* @param clazz    数据模型类。* @param <T>      数据模型的类型。* @return 数据模型列表。*/public static <T> List<T> readExcel(String fileName, Class<T> clazz) {ExcelDataListener<T> listener = new ExcelDataListener<>();List<T> dataModels = new ArrayList<>();try {EasyExcel.read(fileName, clazz, listener).sheet().doRead();dataModels = listener.getDataModels();} catch (Exception e) {e.printStackTrace();}return dataModels;}/*** Excel 数据读取监听器。** @param <T> 数据模型的类型。*/public static class ExcelDataListener<T> implements ReadListener<T> {private List<T> dataModels = new ArrayList<>();@Overridepublic void invoke(T dataModel, AnalysisContext context) {dataModels.add(dataModel);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 所有数据解析完成后的操作}public List<T> getDataModels() {return dataModels;}}/*** 将 MultipartFile 转换为 File 对象。** @param file MultipartFile 对象。* @return 转换后的 File 对象。* @throws IOException 如果文件写入失败。*/public static File convert(MultipartFile file) throws IOException {if (!file.isEmpty()) {File convFile = new File(Objects.requireNonNull(file.getOriginalFilename()));try (var fos = new FileOutputStream(convFile)) {fos.write(file.getBytes());}return convFile;}throw new IOException("Could not convert the uploaded file.");}}

如果我们现在有一个实体类,如下:

package com.xiaobai.easyexceldemo.domain;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;/*** * @TableName easy_demo*/
@TableName(value ="easy_demo")
@Data
public class EasyDemo implements Serializable {/*** */@TableIdprivate Integer id;/*** */private String name;/*** */private String password;/*** */private String email;/*** */private String qq;/*** */private String address;/*** */private String nameSpace;@TableField(exist = false)private static final long serialVersionUID = 1L;
}

 此时我们我们有一个表格,数据如下:

测试:方式一,直接映射

此时我们映射的时候,需要按照表格的列新创建一个中间类。

@Data
public class EasyDemoDto {/****/private String name;/****/private String password;/****/private String email;/****/private String qq;/****/private String address;/****/private String nameSpace;
}

这个类需要按照表格的列进行按照顺序排列,才可以映射上。

现在我们调换一下(name,password)字段的顺序,看一下结果:

所以直接映射的时候一定要注意,字段和excel表格列顺序一致

测试:方式二,注解映射

在实体中添加注解@ExcelProperty("列名"),映射excel表中的列名,进行映射数据。

@Data
public class EasyDemoDto {/****/@ExcelProperty("密码")private String password;/****/@ExcelProperty("名称")private String name;/****/@ExcelProperty("邮箱")private String email;/****/@ExcelProperty("qq")private String qq;/****/@ExcelProperty("地址")private String address;/****/@ExcelProperty("空间")private String nameSpace;
}

EasyExcel中注解说明 

@ExcelProperty: 用于指定实体类属性与 Excel 列的映射关系。

public class Student {@ExcelProperty("学生姓名")private String name;// 其他属性和getter/setter方法
}

@DateTimeFormat: 用于指定日期时间格式,与@ExcelProperty一起使用。

@ExcelProperty("出生日期")
@DateTimeFormat("yyyy-MM-dd")
private Date birthDate;

@NumberFormat: 用于指定数字格式,与@ExcelProperty一起使用。

@ExcelProperty("分数")
@NumberFormat("#.##")
private double score;

@ColumnWidth: 用于指定列宽。

public class Product {@ExcelProperty("产品名称")@ColumnWidth(20)private String name;// 其他属性和getter/setter方法
}

@ContentFontStyle: 用于定义内容单元格的字体样式。

@ExcelProperty("备注")
@ContentFontStyle(name = "微软雅黑", size = 12, isBold = true)
private String comment;

@ContentLoopMerge: 用于在循环写入时合并单元格。

public class SalesRecord {@ExcelProperty("产品名称")@ContentLoopMerge(startRow = 1, endRow = 3)private String productName;// 其他属性和getter/setter方法
}

@ContentRowHeight: 用于设置内容行高。

@ExcelProperty("详细描述")
@ContentRowHeight(value = 50)
private String description;

@ContentStyle: 用于定义内容单元格的样式。

@ExcelProperty("数值")
@ContentStyle(fillForegroundColor = 3, fillPatternType = FillPatternType.SOLID_FOREGROUND)
private double value;

@HeadFontStyle: 用于定义表头单元格的字体样式。

public class Employee {@ExcelProperty("工号")@HeadFontStyle(name = "宋体", size = 14, isBold = true)private String employeeId;// 其他属性和getter/setter方法
}

@HeadRowHeight: 用于设置表头行高。

@ExcelProperty("姓名")
@HeadRowHeight(value = 30)
private String name;

@HeadStyle: 用于定义表头单元格的样式。

@ExcelProperty("部门")
@HeadStyle(fillForegroundColor = 4, fillPatternType = FillPatternType.SOLID_FOREGROUND)
private String department;

@OnceAbsoluteMerge: 用于绝对合并单元格一次。

public class Summary {@ExcelProperty("总计")@OnceAbsoluteMerge(merge = {@ExcelColIndex(1), @ExcelColIndex(2)}, row = 1)private double total;// 其他属性和getter/setter方法
}

@ExcelIgnore: 用于忽略不映射到 Excel 的实体类属性。

private String internalUseOnly;

@ExcelIgnoreUnannotated: 类级别的注解,指定只有使用了@ExcelProperty注解的字段才会写入 Excel。

@ExcelIgnoreUnannotated
public class Product {private String id;@ExcelProperty("产品名称")private String name;// 只有name属性会写入Excel
}

@ExcelColIndex: 用于指定列的索引。

@ExcelProperty("价格")
@ExcelColIndex(2)
private double price;

至此,已经结束啦,获取有不对的地方,还请提出,共勉。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 会议记录|MAS Lab 年度组会记录
  • 低代码开发与数据库:数字化转型的新引擎
  • SpringBoot 集成 kafka
  • Leetcode199二叉树的右视图(java实现)
  • SQLite 创建表:一场数据库里的“造物运动”
  • CAN总线简介
  • docker 拉取镜像出错
  • iOS App快捷指令(App Intents)在系统搜索服务中注册shortcuts
  • 详解JavaScript
  • 更适合编写股票盯盘软件或者量化交易平台的语言是Python还是C
  • Linux之grafana+onealert报警
  • 学习周报-2024.8.31
  • Tensor常见操作、自动微分及手动构建模型
  • 系统演示视频正确的录制顺序
  • 嵌入式Linux C应用编程指南-进程、线程(速记版)
  • ES6指北【2】—— 箭头函数
  • 【EOS】Cleos基础
  • JavaScript 奇技淫巧
  • php ci框架整合银盛支付
  • spring + angular 实现导出excel
  • supervisor 永不挂掉的进程 安装以及使用
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • vue-cli3搭建项目
  • 从0实现一个tiny react(三)生命周期
  • 配置 PM2 实现代码自动发布
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 使用 Docker 部署 Spring Boot项目
  • 我是如何设计 Upload 上传组件的
  • 硬币翻转问题,区间操作
  • 优化 Vue 项目编译文件大小
  • 自制字幕遮挡器
  • ![CDATA[ ]] 是什么东东
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #HarmonyOS:基础语法
  • #Linux(Source Insight安装及工程建立)
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (31)对象的克隆
  • (C#)一个最简单的链表类
  • (LLM) 很笨
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (佳作)两轮平衡小车(原理图、PCB、程序源码、BOM等)
  • (六)vue-router+UI组件库
  • (区间dp) (经典例题) 石子合并
  • (三十五)大数据实战——Superset可视化平台搭建
  • (十八)SpringBoot之发送QQ邮件
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .Net - 类的介绍
  • .net core docker部署教程和细节问题
  • .NET Core跨平台微服务学习资源
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET 动态调用WebService + WSE + UsernameToken
  • .Net 路由处理厉害了
  • .NET 设计模式—适配器模式(Adapter Pattern)