紧接着上一篇,接下来我们实现数据的导入和导出
目录
- 1.数据导入导出
- 1.1.Easy POI
- 1.2.准备工作
- 1.3.实现功能
- 1.4.测试功能
这里的数据具体是指员工数据,员工数据导入导出在实际应用场景中比较常见;比如说我们需要把多个员工的数据一起在某些地方去使用,或者是同时入职了多名员工,按照正常的操作添加员工比较繁琐,这时我们也可以按照指定的
Excel
模板把所有新员工的数据一条一条的写入,然后导入数据,后台就会批量地插入员工数据。
1.1.1.Apache POI简介
开发中经常会涉及到Excel的处理,如导出Excel,导入Excel到数据库中,操作Excel等。
Apache POI使用JAVA编写的免费开源的跨平台的Java API,Apache POI提供API给JAVA程式对Microsoft Office(Excel,Word,PowerPoint,Visio等)格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的字母缩写,意为“可怜的模糊实现”。
官方主页:http://poi.apache.org/index.html
API文档:http://poi.apache.org/apidocs/index.html
缺点:
1.1.2.Easy POI简介
Easy POI功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法。
官方主页:https://gitee.com/lemur/easypoi?_from=gitee_search
API文档:https://opensource.afterturn.cn/doc/easypoi.html#201
测试项目:https://gitee.com/lemur/easypoi-test
Easy POI的主要特点
1.设计精巧,使用简单
2.接口丰富,扩展简单
3.默认值多,write less do more
4.spring mvc支持,web导出可以简单明了
功能
Excel自适应xls和xlsx两种格式,word只支持docx模式
1.Excel导入
2.Excel导出
3.Excel转html
4.word导出
5.pdf导出
1.1.3 Easypoi介绍
Easypoi 为谁而开发
都可以使用Easy POI
Easy POI的目标是什么 Easy POI的目标不是替代poi,而是让一个不懂导入导出的快速使用poi完成Excel和word的各种操作,而不是看很多api才可以完成这样工作。
1.2.1.导入依赖
<dependency>
<groupId>cn.afterturngroupId>
<artifactId>easypoi-spring-boot-starterartifactId>
<version>4.1.2version>
dependency>
1.2.2.修改实体类
因为Emploee实体类中有民族的id以及民族的实体类,我们需要导出的是实体类而不是id所有我们也需要修改Nation实体类(@Excel)。在Employee中具有实体类的属性上加
@ExcelEntity
注解。但是数据的导入又需要将像Nation这样的实体类属性的ID传入,这样才能实现批量添加。这里有两种方法:①通过SQL语句用户实体类获取该ID,但是我们一名员工中有5个这样的属性,那么就需要查询5次数据库,100名员工就需查500次,10000名查50000次,非常消耗性能,甚至会造成内存溢出。
②重写EqualsAndHashCode方法,因为我们的民族和政治面貌、部门、职称、职位有固定个数,并且不会频繁更改,那么name属性是唯一的话就能够根据name属性知道创建的对象是不是唯一的,对象唯一的话,就能拿到对象的ID(前提:name属性基本不会改变)。
Employee.java
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_employee")
@ApiModel(value="Employee对象", description="")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "员工编号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "员工姓名")
@Excel(name = "员工姓名")
private String name;
@ApiModelProperty(value = "性别")
@Excel(name = "性别")
private String gender;
@ApiModelProperty(value = "出生日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
@Excel(name = "出生日期", width = 20, format = "yyyy-MM-dd")
private LocalDate birthday;
@ApiModelProperty(value = "身份证号")
@Excel(name = "身份证号", width = 30)
private String idCard;
@ApiModelProperty(value = "婚姻状况")
@Excel(name = "婚姻状况")
private String wedlock;
@ApiModelProperty(value = "民族")
private Integer nationId;
@ApiModelProperty(value = "籍贯")
@Excel(name = "籍贯")
private String nativePlace;
@ApiModelProperty(value = "政治面貌")
private Integer politicId;
@ApiModelProperty(value = "邮箱")
@Excel(name = "邮箱", width = 10)
private String email;
@ApiModelProperty(value = "电话号码")
@Excel(name = "电话号码", width = 15)
private String phone;
@ApiModelProperty(value = "联系地址")
@Excel(name = "联系地址", width = 40)
private String address;
@ApiModelProperty(value = "所属部门")
private Integer departmentId;
@ApiModelProperty(value = "职称ID")
private Integer jobLevelId;
@ApiModelProperty(value = "职位ID")
private Integer posId;
@ApiModelProperty(value = "聘用形式")
@Excel(name = "聘用形式")
private String engageForm;
@ApiModelProperty(value = "最高学历")
@Excel(name = "最高学历")
private String tiptopDegree;
@ApiModelProperty(value = "所属专业")
@Excel(name = "所属专业")
private String specialty;
@ApiModelProperty(value = "毕业院校")
@Excel(name = "毕业院校")
private String school;
@ApiModelProperty(value = "入职日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
@Excel(name = "入职日期", width = 20, format = "yyyy-MM-dd")
private LocalDate beginDate;
@ApiModelProperty(value = "在职状态")
@Excel(name = "在职状态")
private String workState;
@ApiModelProperty(value = "工号")
@Excel(name = "工号")
private String workID;
@ApiModelProperty(value = "合同期限")
@Excel(name = "合同期限", suffix = "年")
private Double contractTerm;
@ApiModelProperty(value = "转正日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
@Excel(name = "转正日期", width = 20, format = "yyyy-MM-dd")
private LocalDate conversionTime;
@ApiModelProperty(value = "离职日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
private LocalDate notWorkDate;
@ApiModelProperty(value = "合同起始日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
@Excel(name = "合同起始日期", width = 20, format = "yyyy-MM-dd")
private LocalDate beginContract;
@ApiModelProperty(value = "合同终止日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
@Excel(name = "合同终止日期", width = 20, format = "yyyy-MM-dd")
private LocalDate endContract;
@ApiModelProperty(value = "工龄")
private Integer workAge;
@ApiModelProperty(value = "工资账套ID")
@Excel(name = "工资账套ID")
private Integer salaryId;
@ApiModelProperty(value = "民族")
@TableField(exist = false)
@ExcelEntity(name = "民族")
private Nation nation;
@ApiModelProperty(value = "政治面貌")
@TableField(exist = false)
@ExcelEntity(name = "政治面貌")
private PoliticsStatus politicsStatus;
@ApiModelProperty(value = "部门")
@TableField(exist = false)
@ExcelEntity(name = "部门")
private Department department;
@ApiModelProperty(value = "职称")
@TableField(exist = false)
@ExcelEntity(name = "职称")
private Joblevel joblevel;
@ApiModelProperty(value = "职位")
@TableField(exist = false)
@ExcelEntity(name = "职位")
private Position position;
@ApiModelProperty(value = "工资账套")
@TableField(exist = false)
private Salary salary;
}
Nation.java
@Data
@NoArgsConstructor
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = false, of = "name")
@TableName("t_nation")
@ApiModel(value="Nation对象", description="")
public class Nation implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "民族")
@Excel(name = "民族")
@NonNull
private String name;
}
同样的道理,修改政治面貌、部门、职称、职位对应的实体类
PoliticsStatus.java
@Data
@NoArgsConstructor
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = false, of = "name")
@TableName("t_politics_status")
@ApiModel(value="PoliticsStatus对象", description="")
public class PoliticsStatus implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "政治面貌")
@Excel(name = "政治面貌")
@NonNull
private String name;
}
Department.java
@Data
@RequiredArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false, of = "name")
@TableName("t_department")
@ApiModel(value="Department对象", description="")
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "部门名称")
@Excel(name = "部门")
@NonNull
private String name;
......
}
Joblevel.java
@Data
@NoArgsConstructor
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = false, of = "name")
@TableName("t_joblevel")
@ApiModel(value="Joblevel对象", description="")
public class Joblevel implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "职称名称")
@Excel(name = "职称")
@NonNull
private String name;
@ApiModelProperty(value = "职称等级")
private String titleLevel;
@ApiModelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
private LocalDateTime createDate;
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
}
Position.java
@Data
@RequiredArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false, of = "name")
@TableName("t_position")
@ApiModel(value="Position对象", description="")
public class Position implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "职位")
@Excel(name = "职位")
@NonNull
private String name;
@ApiModelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
private LocalDateTime createDate;
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
}
1.3.1.导出/入员工数据
EmployeeController.java
@RestController
@RequestMapping("/employee/basic")
public class EmployeeController {
......
/**
* 注释中加上produces = "application/octet-stream",防止中文乱码
*
* @param response
*/
@ApiOperation(value = "导出员工数据")
@GetMapping(value = "/export", produces = "application/octet-stream")
public void exportEmployee(HttpServletResponse response) {
List<Employee> employeeList = employeeService.getEmployee(null);
ExportParams params = new ExportParams("员工表", "员工表", ExcelType.HSSF);
Workbook workbook = ExcelExportUtil.exportExcel(params, Employee.class, employeeList);
ServletOutputStream outputStream = null;
try {
// 使用流形式传输
response.setHeader("content-type", "application/octet-stream");
// 防止中文乱码
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("员工表.xls", "UTF-8"));
outputStream = response.getOutputStream();
workbook.write(outputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != outputStream) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@ApiOperation(value = "导入员工数据")
@PostMapping("/import")
public RespBean importEmployee(MultipartFile file) {
ImportParams params = new ImportParams();
// 去掉标题行
params.setTitleRows(1);
List<Nation> nationList = nationService.list();
List<PoliticsStatus> politicsStatusList = politicsStatusService.list();
List<Department> departmentList = departmentService.list();
List<Joblevel> joblevelList = joblevelService.list();
List<Position> positionList = positionService.list();
try {
List<Employee> list = ExcelImportUtil.importExcel(file.getInputStream(), Employee.class, params);
list.forEach(employee -> {
// 民族id
Integer nationId = nationList.get(nationList.indexOf(new Nation(employee.getNation().getName()))).getId();
employee.setNationId(nationId);
// 政治面貌id
Integer politicsStatusId = politicsStatusList.get(politicsStatusList.indexOf(new PoliticsStatus(employee.getPoliticsStatus().getName()))).getId();
employee.setPoliticId(politicsStatusId);
// 部门id
Integer departmentId = departmentList.get(departmentList.indexOf(new Department(employee.getDepartment().getName()))).getId();
employee.setDepartmentId(departmentId);
// 职称id
Integer joblevelId = joblevelList.get(joblevelList.indexOf(new Joblevel(employee.getJoblevel().getName()))).getId();
employee.setJobLevelId(joblevelId);
// 职位id
Integer positionId = positionList.get(positionList.indexOf(new Position(employee.getPosition().getName()))).getId();
employee.setPosId(positionId);
});
if (employeeService.saveBatch(list)) {
return RespBean.success("导入成功!");
}
} catch (Exception e) {
e.printStackTrace();
}
return RespBean.error("导入失败!");
}
}
导入数据这里就不演示了,有兴趣的同学可以自行测试。
到这里数据的导入和导出就完成了,下一篇博客实现员工工资账套和个人中心:
Authentication对象实现个人心中功能模块