用户上传一份Excel,服务器端校验Excel内数据的准确性,如有不准确的数据,对Excel对应标红并插入问题批注。返回给用户,如果数据全部校验合格,则进行插库处理。
@ApiOperation(value = "用户信息上传", notes = " \n author:RenShiWei 2020/11/28")
@AnonymousPostMapping(value = "/uploadFile")
public Result<Object> uploadFile(@RequestPart("file") MultipartFile file, HttpServletResponse response) throws JSONException {
JSONObject jsonObject = businessService.fileHandle(file, response);
if (jsonObject.getBoolean("isSuccess")) {
return Result.success(ResultEnum.SUCCESS_UPLOAD, jsonObject.getString("fileName"));
} else {
return Result.error(ResultEnum.FAIL_UPLOAD, jsonObject.getString("fileName"));
}
}
//上传文件
String fileName = fileService.upload(file);
File excelFile = fileService.loadFile(fileName);
//读取文件
ExcelWriter writer = ExcelUtil.getWriter(excelFile);
//设置工作视窗
Workbook workbook = writer.getWorkbook();
//获取第一张图标
Sheet sheetAt = workbook.getSheetAt(0);
格式化单元格(主要清除批注和单元格背景颜色,因之后我们要对问题数据做标记)
在单元格数据范围内,为所有空单元格生成一个单元格(某一列是数字类型时,如果单元格内容为空,则提示无此单元格,对单元格进行操作时会报null,文本及其他类型单元格没有发现此异常)
//初始化单元格样式/注释/ 1
for (int a = 0; a < titleMap.size(); a++) {
for (int b = 1; b <= rowNum; b++) {
//所有空单元格设置有单元格
if (ObjectUtil.isNull(sheetAt.getRow(b).getCell(a))) {
sheetAt.getRow(b).createCell(a);
}
Cell cell = sheetAt.getRow(b).getCell(a);
//设置默认值和样式
if (ObjectUtil.isNotNull(cell)) {
CellStyle cellStyle = writer.createCellStyle();
cellStyle.setFillPattern(FillPatternType.NO_FILL);
cell.setCellStyle(cellStyle);
//移除注释
cell.removeCellComment();
}
}
}
public void recordErrorCell(Cell cell, String error) {
errorNum++;
// 设置样式格式,设置发生错误时,要设置的单元格背景颜色
StyleSet styleError = writer.getStyleSet();
// 第二个参数表示是否也设置头部单元格背景
styleError.setBackgroundColor(IndexedColors.RED, false);
//设置默认值和样式
CellUtil.setCellValue(cell, cell, styleError, false);
//移除注释
if (ObjectUtil.isNotNull(cell)) {
//移除注解
cell.removeCellComment();
//设置注解:方式二
Sheet sheet = writer.getWorkbook().getSheetAt(0);
Drawing drawing = sheet.createDrawingPatriarch();
CreationHelper factory = sheet.getWorkbook().getCreationHelper();
ClientAnchor anchor = factory.createClientAnchor();
Comment comment = drawing.createCellComment(anchor);
RichTextString str = factory.createRichTextString(error);
comment.setString(str);
comment.setAuthor("Auto+");
cell.setCellComment(comment);
}
//设置注释 无效 这是hutool提供的批注设置工具类,会产生移除批注之后,不能再次设置的问题
// CellUtil.setComment(cell, error, null, null);
}
//空值判断和数据校验 2
for (int a = 1; a <= rowNum; a++) {
Cell cellName = sheetAt.getRow(a).getCell(name);
Cell cellUserName = sheetAt.getRow(a).getCell(username);
Cell cellDept = sheetAt.getRow(a).getCell(dept);
Cell cellPhone = sheetAt.getRow(a).getCell(phone);
Cell cellEmail = sheetAt.getRow(a).getCell(email);
//手机号类型设置
if (!cellPhone.getCellTypeEnum().equals(CellType.STRING)) {
cellPhone.setCellType(CellType.STRING);
}
//空值判断
if (StrUtil.isEmpty(cellName.getStringCellValue())) {
recordErrorCell(cellName, "姓名不能为空");
}
if (StrUtil.isEmpty(cellUserName.getStringCellValue())) {
recordErrorCell(cellUserName, "姓名拼音不能为空");
} else {
//通过查库,校验用户名是否正确. 如果用户名存在,邮箱和手机号其一不一样,则数据错误
User user = userMapByUserName.get(cellUserName.getStringCellValue());
if (ObjectUtil.isNotNull(user)) {
if (!cellEmail.getStringCellValue().equals(user.getEmail()) && !cellPhone.getStringCellValue().equals(user.getPhone())) {
recordErrorCell(cellUserName, "姓名拼音与数据库中的姓名拼音重复,请手动标识姓名拼音或将其手机号或者邮箱号与数据库内容保持一致。");
}
}
}
if (StrUtil.isEmpty(cellDept.getStringCellValue())) {
recordErrorCell(cellDept, "所在单位不能为空");
}
if (StrUtil.isEmpty(cellPhone.getStringCellValue())) {
recordErrorCell(cellPhone, "手机号不能为空");
}
//数据正确性校验
//校验部门
if (StrUtil.isNotEmpty(cellDept.getStringCellValue()) && ObjectUtil.isNull(deptList.get(cellDept.getStringCellValue()))) {
recordErrorCell(cellDept, "该单位不存在:请注意空格,逗号或查看单位是否存在等");
} else {
//校验部门权限
if (!SecurityUtils.judgeOperationDataScope(deptList.get(cellDept.getStringCellValue()))) {
recordErrorCell(cellDept, "当前人员所在单位超出您所在权限范围,请更换其单位为您当前所在部门或所在单位的子单位");
}
}
}
//手机号类型设置
if (!cellPhone.getCellTypeEnum().equals(CellType.STRING)) {
cellPhone.setCellType(CellType.STRING);
}
//校验部门
if (StrUtil.isNotEmpty(cellDept.getStringCellValue()) && ObjectUtil.isNull(deptList.get(cellDept.getStringCellValue()))) {
recordErrorCell(cellDept, "该单位不存在:请注意空格,逗号或查看单位是否存在等");
} else {
//校验部门权限
if (!SecurityUtils.judgeOperationDataScope(deptList.get(cellDept.getStringCellValue()))) {
recordErrorCell(cellDept, "当前人员所在单位超出您所在权限范围,请更换其单位为您当前所在部门或所在单位的子单位");
}
//判断重复元素 3
for (int a = 1; a < rowNum; a++) {
Cell cellUserName = sheetAt.getRow(a).getCell(username);
Cell cellEmail = sheetAt.getRow(a).getCell(email);
for (int b = a + 1; b <= rowNum; b++) {
Cell cellUserNameTwo = sheetAt.getRow(b).getCell(username);
Cell cellEmailTwo = sheetAt.getRow(b).getCell(email);
Cell cellIdcardTwo = sheetAt.getRow(b).getCell(idcard);
//姓名拼音-用户名
if (StrUtil.isNotEmpty(cellUserName.getStringCellValue())
&& StrUtil.isNotEmpty(cellUserNameTwo.getStringCellValue())
&& cellUserName.getStringCellValue().equals(cellUserNameTwo.getStringCellValue())) {
recordErrorCell(cellUserName, "姓名拼音不能重复,请修改。如:张三/zhangsan01");
}
//邮箱
if (StrUtil.isNotEmpty(cellEmail.getStringCellValue())
&& StrUtil.isNotEmpty(cellEmailTwo.getStringCellValue())
&& cellEmail.getStringCellValue().equals(cellEmailTwo.getStringCellValue())) {
recordErrorCell(cellEmail, "邮箱不能重复,请修改。");
}
}
}
//关闭writer
writer.close();
if (errorNum > 0) {
//数据检验不正确
// downLoadErrorReport(response);
//生成返回对象
resultJson.put("isSuccess", false);
resultJson.put("message", "插入失败,请查看报告文件");
resultJson.put("fileName", fileName);
return resultJson;
} else {
ExcelReader reader = ExcelUtil.getReader(excelFile,0);
parseVarToNum(reader);
insertUploadUser(reader);
insertUploadLibeller(reader);
//生成返回对象
resultJson.put("isSuccess", true);
resultJson.put("message", "插入成功");
resultJson.put("fileName", fileName);
return resultJson;
}
if (errorNum > 0) {
//数据检验不正确
// downLoadErrorReport(response);
//生成返回对象
resultJson.put("isSuccess", false);
resultJson.put("message", "插入失败,请查看报告文件");
resultJson.put("fileName", fileName);
return resultJson;
} else {
ExcelReader reader = ExcelUtil.getReader(excelFile,0);
parseVarToNum(reader);
insertUploadUser(reader);
insertUploadLibeller(reader);
//生成返回对象
resultJson.put("isSuccess", true);
resultJson.put("message", "插入成功");
resultJson.put("fileName", fileName);
return resultJson;
}
ExcelReader reader = ExcelUtil.getReader(excelFile,0);
public void parseVarToNum(ExcelReader reader) {
//将文字类型的cell转换成数字
//列数量
int rowCount = reader.getRowCount();
//被反映人数据转换
for (int b = 1; b < rowCount; b++) {
Cell cellNation = reader.getCell(nation, b);
Cell cellGender = reader.getCell(gender, b);
Cell cellRegion = reader.getCell(region, b);
Cell cellDept = reader.getCell(dept, b);
Cell cellJob = reader.getCell(job, b);
Cell cellDeptType = reader.getCell(deptType, b);
Cell cellRanks = reader.getCell(rank, b);
cellNation.setCellValue(nationList.get(cellNation.getStringCellValue()));
cellGender.setCellValue(genderList.get(cellGender.getStringCellValue()));
cellRegion.setCellValue(regionList.get(cellRegion.getStringCellValue()));
cellDept.setCellValue(deptList.get(cellDept.getStringCellValue()));
cellJob.setCellValue(jobList.get(cellJob.getStringCellValue()));
cellDeptType.setCellValue(deptTypeList.get(cellDeptType.getStringCellValue()));
cellRanks.setCellValue(rankList.get(cellRanks.getStringCellValue()));
}
}
//用户对应标题
Map<String, String> userMap = new LinkedHashMap<>();
userMap.put("姓名", "nick_name");
userMap.put("姓名拼音", "username");
userMap.put("所在单位", "dept_id");
userMap.put("性别", "gender");
userMap.put("手机号", "phone");
userMap.put("Eamil", "email");
reader.setHeaderAlias(userMap);
方式二:获取标题单元格,逐一设置
name/nation,表示对应的标题所在的列队坐标
reader.getCell(name, 0).setCellValue("name");
reader.getCell(nation, 0).setCellValue("nation_id");
reader.getCell(gender, 0).setCellValue("gender");
reader.getCell(birth, 0).setCellValue("birth");
reader.getCell(idcard, 0).setCellValue("idcard");
reader.getCell(region, 0).setCellValue("region_id");
reader.getCell(dept, 0).setCellValue("dept");
reader.getCell(job, 0).setCellValue("job_id");
reader.getCell(deptType, 0).setCellValue("dept_type");
reader.getCell(rank, 0).setCellValue("ranks");
List<User> userList = reader.readAll(User.class);
List<TLibellee> libellerList = reader.readAll(TLibellee.class);
//校验数据
String fileName = "C:\\Users\\DELL\\Desktop\\xf-suer.xlsx";
//读文件(用户获取文件数据)
ExcelReader reader = ExcelUtil.getReader(fileName);
//写文件(用于编辑文件数据)
ExcelWriter writer = ExcelUtil.getWriter(fileName);
//获取工作视图
Workbook workbook = writer.getWorkbook();
//获取第一张图表
Sheet sheetAt = workbook.getSheetAt(0);
//获取图表第一行
Row row = sheetAt.getRow(0);
//获取第一行第五个单元格
Cell cell = row.getCell(5);
//设置单元格注释
CellUtil.setComment(cell, "此处信息有误", null, null);
//删除单元格注释
cell.removeCellComment();
// 定义单元格样式 方式一:无误
StyleSet style = writer.getStyleSet();
// 第二个参数表示是否也设置头部单元格背景
style.setBackgroundColor(IndexedColors.RED, false);
//设置单元格的值,以及样式
CellUtil.setCellValue(cell, cell.getStringCellValue(), style, false);
//设置单元格的样式 方式二:FillPatternType为背景的填充类型。
// FillPatternType.SOLID_FOREGROUND为纯色填充(使用他时,不论设置什么背景色,都是黑色。所以未采用这种方式)
//FillPatternType.NO_FILL 默认,表示不填充。
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFillPattern(FillPatternType.BIG_SPOTS);
cellStyle.setFillBackgroundColor(IndexedColors.RED.getIndex());
cell.setCellStyle(cellStyle);
//multipartfile转换成excelReater
MultipartFile file = new .....
InputStream inputStream = file.getInputStream();
File file1 = new File(file.getOriginalFilename());
BigExcelWriter bigWriter = ExcelUtil.getBigWriter(file1);
//设置日期类型
CellStyle cellStyle = sheetAt.getColumnStyle(sheetMessage.getBirth());
cellStyle.setDataFormat(sheetAt.getWorkbook().getCreationHelper().createDataFormat().getFormat("m/d/yy"));
cellBirth.setCellStyle(cellStyle);
坑:
excel为文本类型时,不输入值 cell不为空
excel为数字类型时,不输入值 cell为空