easypoi实现Excel模板导入(包含文档下载的与前端交互回显)

CodeR# 2024-07-19 17:03:01 阅读 86

实战使用easypoi完成Excel模板导入,且包含一对多的导入,模板文件的下载 和 下载成功后浏览器页面的回显功能。

目录

1、后端代码

 2、前端代码

3、导入文件的坑

3.1无法读取某列的数据

3.2一对多的导入注意事项


模板文件的样例:

导入成功后的提示:


1、后端代码

依赖:

使用easypoi依赖和hutool包

<code><dependency>

<groupId>cn.afterturn</groupId>

<artifactId>easypoi-base</artifactId>

<version>4.3.0</version>

</dependency>

<dependency>

<groupId>cn.afterturn</groupId>

<artifactId>easypoi-web</artifactId>

<version>4.3.0</version>

</dependency>

<dependency>

<groupId>cn.afterturn</groupId>

<artifactId>easypoi-annotation</artifactId>

<version>4.3.0</version>

</dependency>

<!-- hutool工具类 版本:<hutool.version>5.3.8</hutool.version> -->

<dependency>

<groupId>cn.hutool</groupId>

<artifactId>hutool-core</artifactId>

<version>5.3.8</version>

</dependency>

<dependency>

<groupId>cn.hutool</groupId>

<artifactId>hutool-crypto</artifactId>

<version>5.3.8</version>

</dependency>

<dependency>

<groupId>cn.hutool</groupId>

<artifactId>hutool-extra</artifactId>

<version>5.3.8</version>

</dependency>

<dependency>

<groupId>cn.hutool</groupId>

<artifactId>hutool-http</artifactId>

<version>5.3.8</version>

</dependency>

接口:

@Autowired

private ImportExpertListExcelUtil importExpertListExcelUtil;

/**

* 通过excel导入数据

*/

@PostMapping(value = "/importExcel")

public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {

return importExpertListExcelUtil.importExcel(request, response, ExpertInformation.class);

}

实体类:

@Data

@TableName("expert_information")

public class ExpertInformation implements Serializable {

private static final long serialVersionUID = 1L;

/**

* id

*/

@TableId(type = IdType.ASSIGN_ID)

private java.lang.String id;

/**

* 姓名

*/

@NotNull(message = "姓名不能为空")

@Excel(name = "姓名", needMerge = true, width = 15)

private java.lang.String name;

/**

* 国家/地区

*/

@Excel(name = "国家/地区", needMerge = true, width = 15)

private java.lang.String country;

/**

* 证件类型

*/

@Excel(name = "证件类型", needMerge = true, width = 15)

private java.lang.String credentialType;

/**

* 证件号码

*/

@NotNull(message = "证件号码不能为空")

@Excel(name = "证件号码", needMerge = true, width = 30)

private java.lang.String credentialNumber;

/**

* 毕业学校

*/

@Excel(name = "毕业学校", needMerge = true, width = 30)

private java.lang.String graduationSchool;

/**

* 学历

*/

@Excel(name = "学历", needMerge = true, width = 15)

private java.lang.String degree;

/**

* 联系电话

*/

@NotNull(message = "联系电话不能为空")

@Excel(name = "联系电话", needMerge = true, width = 15)

private java.lang.String phone;

/**

* 邮箱

*/

@Excel(name = "邮箱", needMerge = true, width = 15)

@NotNull(message = "邮箱不能为空")

private java.lang.String mail;

/**

* 开户银行名称

*/

@Excel(name = "开户银行名称", needMerge = true, width = 30)

private java.lang.String openedBankName;

/**

* 其开户银行名称

*/

@Excel(name = "其开户银行名称(选择 其他 时展示)", width = 30)

@TableField(updateStrategy = FieldStrategy.IGNORED) //更新操作时,无论字段是否为 空字符串,都会进行更新

private java.lang.String otherOpenedBankName;

/**

* 银行账户

*/

@Excel(name = "银行账户", needMerge = true, width = 30)

private java.lang.String bankAccount;

/**

* 评审范围

*/

@Excel(name = "评审范围", width = 15)

@TableField(updateStrategy = FieldStrategy.IGNORED) //更新操作时,无论字段是否为 空字符串,都会进行更新

private java.lang.String scopeAssessment;

@TableField(exist = false)

private List<String> checkedList;

/**

* 单位-列表

*/

@TableField(exist = false)

@ExcelCollection(name = "工作经历")

private List<ExpertWorkExperience> unit;

/**

* 单位名称

*/

@TableField(exist = false)

private String companyName;

}

@Data

@TableName("expert_work_experience")

public class ExpertWorkExperience implements Serializable {

private static final long serialVersionUID = 1L;

/**

* id

*/

@TableId(type = IdType.ASSIGN_ID)

private java.lang.String id;

/**

* 专家主键id

*/

private java.lang.String expertInformationId;

/**

* 单位名称

*/

@Excel(name = "单位名称", width = 30)

private java.lang.String companyName;

/**

* 职位

*/

@Excel(name = "职位", width = 15)

private java.lang.String post;

}

工具类方法:

@Slf4j

@Component

public class ImportExpertListExcelUtil {

/**

* 通过excel导入数据

*/

public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<ExpertInformation> clazz) {

MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();

//错误集合

List<String> errorMsg = new ArrayList<>();

List<ExpertWorkExperience> totalExpertWorkExperienceList = new LinkedList<>();

for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {

MultipartFile file = entity.getValue();// 获取上传文件对象

ImportParams params = new ImportParams();

params.setTitleRows(2);

params.setHeadRows(1);

params.setNeedSave(true);

try {

long start = System.currentTimeMillis();

//导入Excel格式校验,看匹配的字段文本概率

Boolean t = ExcelImportCheckUtil.check(file.getInputStream(), ExpertInformation.class, params);

if (!t) {

throw new RuntimeException("导入Excel校验失败 !");

}

List<ExpertInformation> expertInformationList = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params);

log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");

return Result.ok(String.format("文件导入成功:%s 行", expertInformationList.size());

} catch (Exception e) {

log.error(e.getMessage(), e);

return Result.error("文件导入失败:" + e.getMessage());

} finally {

try {

file.getInputStream().close();

} catch (Exception e) {

e.printStackTrace();

}

}

}

return Result.error("文件导入失败!");

}

}

List<ExpertInformation> expertInformationList = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params);

在这行代码导入Excel后,返回的数据可以根据自己的业务做一些校验,我这里当时对它的证件号码和手机号、邮箱这些字段做一些正则校验,这个代码我就省略了,只是demo演示一下导入Excel。

 2、前端代码

导入按钮的功能:

这里有一对多的导入,这个导入按钮的代码就省略了,每个项目的前端使用框架不一样,封装的组件和方法也不一样,根据自身情况去官方开发文档查看即可。

--我这里前端框架使用的是ant-design的vue2版本,如果和我情况一样,可以评论问我,无偿分享这里的前端代码。

模板下载:

这里让用户把模板下载出来,再去填写数据,避免因为导入的Excel字段和实体类使用注解的name不一致。导致无法读取该列的数据。

@Excel(name = "单位名称", width = 30)

private String companyName;

 这个代码在这文章中t提供了文件下载,前端下载成功弹窗回显 和 注意事项,需要的可以去这个文章参考代码。

模板下载

icon-default.png?t=N7T8

https://blog.csdn.net/RYH6817/article/details/136240011

3、导入文件的坑

3.1无法读取某列的数据

        这里一定要注意使用注解中的name值,必须和Excel列的名字要一致,不然无法识别,就默认这列数据为null。

 导入的Excel字段和实体类使用注解的name不一致。导致无法读取该列的数据。

<code> @Excel(name = "单位名称", width = 30)

private String companyName;

3.2一对多的导入注意事项

首先就是在父表ExpertInformation中有子表字段,

例如:在ExpertInformation中添加一个子表的list集合。

<code> /**

* 单位-列表

*/

@TableField(exist = false)

@ExcelCollection(name = "工作经历")

private List<ExpertWorkExperience> unit;

这里需要使用注解 @ExcelCollection(name = "工作经历") ,而且也必须和页面的列名一致。不然也是无法识别子表的数据。

 还有就是这个列名 “工作经历” 必须合并单元格,包含其子表需要导入的字段。我这里子表只导入:”单位名称“和”职位“两个字段。

完整的一对多模板表格如图:

 子表 ExpertWorkExperience 的字段,也需要使用注解 @Excel(name = "单位名称", width = 30)



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。