问题
在使用easyPoi导入日期字段时,因为导入的日期同时包含了时间类型和文本类型,使用Date接收会导致文本类型读取为null,使用String接收会导致时间类型读取为null。
解决办法
统一使用String接收,然后使用importFormat = "yyyy-MM-dd"格式化即可接收两种类型日期。
@Excel(name = "xx日期",importFormat = "yyyy-MM-dd")
private String dateExcel;
private Date enDate;
使用场景
在用户导入Excel时需要反馈具体行数的具体错误内容,通过实现EasyPoi提供的校验接口IExcelVerifyHandler进行自定义校验,只要匹配其中一项日期格式就转换为Date类型赋值给enDate用于后期赋值,都没匹配成功则拼接返回内容,以下是自定义校验类。
@Component
public class AppImportVerify implements IExcelVerifyHandler<AnnouncementScrappingExcel> {
private final List<SimpleDateFormat> DATE_FORMATS = Arrays.asList(
new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyy/MM/dd"),
new SimpleDateFormat("yyyy.MM.dd"),
new SimpleDateFormat("yyyy年MM月dd日")
);
@Override
public ExcelVerifyHandlerResult verifyHandler(AnnouncementScrappingExcel scrappingExcel) {
ExcelVerifyHandlerResult result = new ExcelVerifyHandlerResult();
// 在这里定义错误信息列表
StringBuilder errorMessages = new StringBuilder();
boolean flag = true;
String detainTime = scrappingExcel.getDetainTimeExcel();
String announceTime = scrappingExcel.getAnnounceTimeExcel();
try {
if (detainTime != null) {
boolean timeTrue = false;
for (SimpleDateFormat dateFormat : DATE_FORMATS) {
try {
// 关闭宽松模式
dateFormat.setLenient(false);
Date parse = dateFormat.parse(detainTime.toString());
scrappingExcel.setDetainTime(parse);
timeTrue = true;
break;
} catch (Exception e) {
// 尝试下一个格式
}
}
// 校验是否是自定义日期格式(例如yyyy-mm-dd解析得到43780)
if(NumberUtils.isCreatable(detainTime)){
try {
Date parse = HSSFDateUtil.getJavaDate(Double.parseDouble(detainTime));
scrappingExcel.setDetainTime(parse);
timeTrue = true;
}catch (Exception e){
e.printStackTrace();
}
}
if(!timeTrue){
errorMessages.append("扣押日期格式错误");
flag =false;
}
}
if (detainTime != null) {
boolean timeTrue = false;
for (SimpleDateFormat dateFormat : DATE_FORMATS) {
try {
// 关闭宽松模式
dateFormat.setLenient(false);
Date parse = dateFormat.parse(announceTime.toString());
scrappingExcel.setAnnounceTime(parse);
timeTrue = true;
break;
} catch (Exception e) {
// 尝试下一个格式
}
}
if(!timeTrue){
errorMessages.append("公告日期格式错误");
flag =false;
}
}
} catch (Exception e) {
e.printStackTrace();
}
if(flag){
result.setSuccess(true);
}else {
result.setSuccess(false);
scrappingExcel.setMsg("第" + scrappingExcel.getNo() +"行:" + errorMessages + "、");
}
return result;
}
}
自定义校验类调用示例,importParams.setNeedVerify(true);importParams.setVerifyHandler(appImportVerify);这两个参数分别代表开启验证和调用的自定义验证类
public Map<String, String> fileToJson(MultipartFile file) {
StringBuilder errorMsg = new StringBuilder();
List<AnnouncementScrappingExcel> scrappingList = new ArrayList<>();
try {
// 提取所有数据行
InputStream inputStream = file.getInputStream();
Workbook workbook = null;
if (file.getOriginalFilename().endsWith(".xls")) {
workbook = new HSSFWorkbook(inputStream);
} else if (file.getOriginalFilename().endsWith(".xlsx")) {
workbook = new XSSFWorkbook(inputStream);
}
int sheetNum = workbook.getNumberOfSheets();
ImportParams importParams = new ImportParams();
// 标题2行,字段两行
importParams.setTitleRows(2);
importParams.setHeadRows(2);
importParams.setNeedVerify(true);
importParams.setVerifyHandler(appImportVerify);
for (int i = 0; i < sheetNum; i++) {
// 获取指定索引的 sheet, 跳过空页(用户传入excel有空页会报错)
if (workbook.getSheetAt(i).getRow(0) == null) {
continue;
}
importParams.setStartSheetIndex(i);
ExcelImportResult<AnnouncementScrappingExcel> result = ExcelImportUtil.importExcelMore(file.getInputStream(), AnnouncementScrappingExcel.class, importParams);
if (result.isVerifyFail()) {
List<String> errorMessages = result.getFailList().stream()
.map(AnnouncementScrappingExcel::getMsg)
.collect(Collectors.toList());
errorMsg.append("导入失败: 在第").append(i + 1).append("页中:").append(String.join(", ", errorMessages));
}
scrappingList.addAll(result.getList().stream().filter(obj -> obj.getPlateNum() != null).collect(Collectors.toList()));
}
} catch (Exception e) {
e.printStackTrace();
}
Map<String, String> resultMap = new HashMap<>(3);
if (StringUtils.isNotBlank(errorMsg)) {
resultMap.put("flag", "false");
resultMap.put("jsonStr", "");
resultMap.put("msg", errorMsg.toString());
return resultMap;
}
// 没有错误格式,继续执行数据存储转换......
}