前言
一直以来,使用EasyPOI做了不少导入导出的需求,但是每次做完都是临时去看官方文档现学现用,正巧最近朋友遇到这么个需求,用到了EasyPOI来完成导入,我也正好整理整理EasyPOI的导入用法。
需求是这样的:现在要在后台导入用户的简历,简历的格式是这样子的:
一个人有多个属性,某些属性如申请职位、薪资是单一属性,即只会有一个值;某些属性如工作经历、教育经历、获奖情况是一组属性,可能会有多组值。现在要将这批简历数据导入到库中。
零、文件准备:
加入 EasyPOI 的依赖
cn.afterturn
easypoi-web
3.2.0
一、定义EasyPOI导入实体类
首先定义一个 EasyPOI 实体类,单个属性使用 @Excel注解声明,name 属性需要与Excel中的表头保持一致,比如 姓名*中的 * 号就不能省略掉。一对多关系使用 @Collection 注解声明,name 是最上方的表头,对应的集合元素类型需要另外定义一个对象,这里因为篇幅问题,只展示一个工作经历以及教育经历对应的集合对象。
@Data
public class TalentUserInputEntity{
@Excel(name = "姓名*")
private String name;
@Excel(name = "性别*")
private Integer gender;
@Excel(name = "手机号*")
private String phone;
@Excel(name = "开始工作时间*")
private Date workTime;
@Excel(name = "民族*")
private String national;
@Excel(name = "语言水平*")
private String languageProficiency;
@Excel(name = "出生日期*")
private Date birth;
@Excel(name = "职位*")
private String jobsName;
@Excel(name = "职位类型*")
private String categoryName;
@Excel(name = "薪资*")
private Integer salary;
@Excel(name = "工作地点*")
private String workArea;
@ExcelCollection(name = "工作经历*")
private List experienceList;
@ExcelCollection(name = "教育经历*")
private List educationList;
@ExcelCollection(name = "获奖情况")
private List awardList;
@ExcelCollection(name = "技能证书")
private List punishmentList;
@Excel(name = "特长")
private String specialty;
}
// 工作经历对象
@Data
public class ExperienceInputEntity {
@Excel(name = "公司名称*")
private String companyName;
@Excel(name = "所在行业*")
private String industry;
@Excel(name = "开始时间*")
private Date beginTime;
@Excel(name = "结束时间*")
private Date finishTime;
@Excel(name = "职位名称*")
private String jobTitle;
@Excel(name = "所属部门*")
private String department;
@Excel(name = "工作内容*")
private String description;
}
// 教育经历对象
@Data
public class EducationInputEntity {
@Excel(name = "学校*")
private String schoolName;
@Excel(name = "学历*")
private Integer record;
@Excel(name = "开始年份*")
private Date beginTime;
@Excel(name = "毕业年份*")
private Date finishTime;
@Excel(name = "专业*")
private String profession;
}
// 省略其他
二、EasyPOI基础导入
这里为方便演示,直接将导入结果转成JSON打印输出。
@PostMapping("/upload")
public Boolean upload(@RequestParam("file") MultipartFile multipartFile) throws Exception {
ImportParams params = new ImportParams();
params.setHeadRows(2);
// params.setTitleRows(0);
List result = ExcelImportUtil.importExcel(multipartFile.getInputStream(),
TalentUserInputEntity.class, params);
System.out.println(JSONUtil.toJsonStr(result));
return true;
}
这里需要注意表头的行数设置一定要正确!否则集合数据将无法读取,可以通过WPS或者office查看实际表头所占用的行数,一定要区分表头与标题的区别,表头是列名称,标题是表头上面的文字,本文示例文件中没有标题,所以setTitleRows为0
三、值替换
使用 postman 或者 Talend API Tester 等工具进行上传 示例文件.xlsx,结果控制台输出了异常,异常如下:
java.lang.NumberFormatException: For input string: "男"
...
cn.afterturn.easypoi.exception.excel.ExcelImportException: Excel 值获取失败
原因是因为数据库中性别字段类型为 Integer 类型的,所以导入对象也设置成了 Integer,而 Excel 中填写的是男/女汉字,自然就出错了,这里就需要使用 easypoi 的 replace 方式来替换最终值,修改 gender 字段上的注解为:
// replace格式为 "替换前的值_替换后的值"
@Excel(name = "性别*", replace = {"男_0", "女_1"})
private Integer gender;
同理,薪资类型和教育经历中的学历需要替换需要的值
@Excel(name = "薪资*", replace = {"3K以下_1", "3K-5K_2", "5K-10K_3", "10K-20K_4", "20K-50K_5", "50K以上_6"})
private Integer salary;
@Excel(name = "学历*", replace ={"初中及以下_1","中专_2","高中_3","大专_4","本科_5","硕士_6","博士_7"})
private Integer record;
再重新尝试导入,控制台输出了导入的JSON内容
[
{
"experienceList": [
{
"finishTime": 1571673600000,
"companyName": "科技公司1",
"jobTitle": "运营",
"description": "运营方案处理",
"industry": "互联网",
"beginTime": 1546358400000,
"department": "运营部"
},
{
"finishTime": 1571673600000,
"companyName": "财务公司",
"jobTitle": "会计",
"description": "审计",
"industry": "财务",
"beginTime": 1574179200000,
"department": "会计部"
}
],
"gender": 0,
"l