1.项目中添加POISpringMVC集成
1.1 导出
1.1.1 Employee
@Entity
@Table(name = "employee")
public class Employee extends BaseDomain{
@Excel(name = "用户名")//一定要和Excel表上面对应上
private String username;
private String password;
@Excel(name = "邮件")
private String email;
@Excel(name = "年龄")
private Integer age;
@Excel(name = "头像",type = 2,savePath = "/images/head")
private String headImage;//图片 头像
@ManyToOne(fetch = FetchType.LAZY)//多对一.多个员工属于一个部门
@JoinColumn(name = "department_id")
@ExcelEntity
private Department department;//部门
- Department
@Entity
@Table(name = "department")
public class Department extends BaseDomain{
@Excel(name = "部门")
private String name;
1.1.2 准备一个按钮《导出》---Employss.jsp
1.1.3 EmployeeController加一个导出功能
//download下载
@RequestMapping("/download")
public String download(ModelMap map, EmployeeQuery query, HttpServletRequest request){
//要导出的数据 获取到
List list = employeeService.queryAll(query);
//主要是为了显示头像
//拿到项目的运行路径-----【绝对路径】
String realPath = request.getServletContext().getRealPath("");//拿到运行然后拼接
//进行拼接,把头像的路径e.getHeadImage()拼接出来----【遍历导出的数据list】
list.forEach(e->System.out.println(realPath + e.getHeadImage()));
//设置导出的Excel的一些参数,表头、页名、版本
ExportParams exportParams = new ExportParams("title", "sheetName", ExcelType.XSSF);
//这个就是导出来的数据 锁定多少列。不可以动
exportParams.setFreezeCol(1);
//数据集合
map.put(NormalExcelConstants.DATA_LIST,list );
//导出实体
map.put(NormalExcelConstants.CLASS,Employee.class);
//文件名称
map.put(NormalExcelConstants.FILE_NAME,"employee");
//参数
map.put(NormalExcelConstants.PARAMS,exportParams);
return NormalExcelConstants.EASYPOI_EXCEL_VIEW;
}
}
1.1.4 当点击导出的时候,出现报错
在配置一个视图解析器【applicationController-mvc.xml】
导出现在没有头像,因为头像找得是绝对路径。他现在无法定位到,他找的是盘符。
- EmployeeController中加上----拿到头像路径【把真实路径拼接出来】
//主要是为了显示头像
//拿到项目的运行路径-----【绝对路径】
String realPath = request.getServletContext().getRealPath("");//拿到运行然后拼接
//进行拼接,把头像的路径e.getHeadImage()拼接出来----【遍历导出的数据list】
list.forEach(e->System.out.println(realPath + e.getHeadImage()));
1.1.5 根据查询条件导出
1.2 导入
1.2.1 新建Controller
@Controller
@RequestMapping("/uploading")
public class uploadingController {
@Autowired
private IDepartmentService departmentService;
@Autowired
private IEmployeeService employeeService;
@RequestMapping("/index")
public String index(){
return "uploading";
}
}
1.2.2 在WEB-INF/views/下面加一个页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%@ include file="/WEB-INF/views/head.jsp"%>
1.2.3 接收文件里面的数据
- 在Controller中在加方法--拿到数据
@RequestMapping("/employeeJudge")
public String employeeJudge(MultipartFile empFile)throws Exception{
ImportParams params = new ImportParams();
params.setHeadRows(1);//不要第0行
List list = ExcelImportUtil.importExcel(empFile.getInputStream(), Employee.class, params);
list.forEach(e->{
Department department = e.getDepartment();//拿部门
if (department!=null){
String name = e.getDepartment().getName();//拿到部门名称
Department byName = departmentService.findByName(name);//根据部门名称拿到对应部门
e.setDepartment(byName);//把部门放到员工对象去
}
employeeService.save(e);//把员工保存到数据库
});
return "uploading";
}
- DepartmentRepository-----------
Department findByName(String name);
- IDepartmentService -----------
Department findByName(String name);
- DepartmentServiceImpl
@Autowired
private DepartmentRepository departmentRepository;
@Override
public Department findByName(String name) {
return departmentRepository.findByName(name);
}
1.2.4 在EmployeeServiceImpl的判断里面加一句判断
传的时候会报错空指针,因为你在保存的时候加了密码加密的方法。传过去的时候没有密码,密码为空 就报500空指针
我们在EmployeeServiceImpl设一个初始密码
- 就是一个三目运算,如果有密码就用它的,如果没有密码就设置初始密码。。。。
//这里加一句代码,设置初始面。因为上传时如果没有密码会报错---[三目运算 如果有就用他的,没有就默认]
String password = StringUtils.isNotBlank(employee.getPassword())?employee.getPassword():"123456";
1.3 Excel导入校验
导入的时候想要做一些验证。比如用户名不能为空、年龄大于18小于60、邮件不能为空、用户名不能重复
- 我们要做的就是 导入---成功的话就不管,如果失败的话就自动下载一个文件,这个文件里面写着失败的某条,并且把失败原因写在里面
1.3.1 导入规范包JSR 303
org.hibernate
hibernate-validator
5.2.4.Final
1.3.2 Employee
@Excel(name = "用户名")//一定要和Excel表上面对应上
@NotNull//该字段不能为空
private String username;
private String password;
@Excel(name = "邮件")
@NotNull
private String email;
@Excel(name = "年龄")
@Max(value = 60,message = "年龄不能超过60")
@Min(value = 18,message = "年龄不能小于18")
private Integer age;
1.3.3 在Controller的方法中添加上验证
//注入闸门写的工具类 专门自定义的验证
@Autowired
private EmployeeExcelVerifyHandler handler;
...
@RequestMapping("/employeeJudge")
public String employeeJudge(MultipartFile empFile, HttpServletResponse response)throws Exception{
ImportParams params = new ImportParams();
params.setHeadRows(1);//不要第0行
params.setNeedVerfiy(true);//让他支持验证
params.setVerifyHandler(handler);//加上咋们自己定义的验证
//拿到导入的数据
ExcelImportResult result= ExcelImportUtil.importExcelMore(empFile.getInputStream(), Employee.class, params);
//成功数据保存
result.getList().forEach(e->{
Department department = e.getDepartment();//拿部门
if (department!=null){
String name = e.getDepartment().getName();//拿到部门名称
Department byName = departmentService.findByName(name);//根据部门名称拿到对应部门
e.setDepartment(byName);//把部门放到员工对象去
}
employeeService.save(e);//把员工保存到数据库
});
//上面是正确了就保存,下面是错误了,导出来
boolean verfiyFail = result.isVerfiyFail();//确认是否有错误数据
if (verfiyFail) {//判断如果有错误信息就。。执行下面方法
Workbook failWorkbook = result.getFailWorkbook();//当判断有就用流导出来
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-disposition", "attachment;filename=employee.xlsx");
response.setHeader("Pragma", "No-cache");//设置不要缓存
OutputStream ouputStream = response.getOutputStream();
failWorkbook.write(ouputStream);
ouputStream.flush();
ouputStream.close();
}
return "uploading";
}
1.3.4 唯一性校验
上面只是判断了不为空可年龄范围,下面来规范用户名不重复(唯一性校验)
新建接口----【工具类EmployeeExcelVerifyHandler 】
/**
* 自定义验证
*/
@Component//不知道什么层 的注解
public class EmployeeExcelVerifyHandler implements IExcelVerifyHandler{
@Autowired
private IEmployeeService employeeService;
@Override
public ExcelVerifyHandlerResult verifyHandler(Employee employee) {
ExcelVerifyHandlerResult excelVerifyHandlerResult = new ExcelVerifyHandlerResult(true);
//通过用户名获取用户
Employee byUsername = employeeService.findByUsername(employee.getUsername());
if (byUsername!=null){
//excelVerifyHandlerResult不为空,就代表这个用户是存在的,就应该添加失败
excelVerifyHandlerResult = new ExcelVerifyHandlerResult(false,"用户名重复");
}
return excelVerifyHandlerResult;
}
}
扫描之后就可以加入注入
- 成功之后直接接入
-
如果有错误数据---导出打印
2、数据字典
-
对于相同的表的抽取,注:没有什么业务意义的