在处理 Excel 导入时,验证模板的正确性是非常关键的一步。本文将介绍如何通过 HolidayExcelListener
类来实现这一功能。该类不仅可以验证模板的正确性,还可以批量处理 Excel 中的数据。以下是该类的详细实现和工作流程。
HolidayExcelListener
类的基本结构
该类继承自 AnalysisEventListener<HolidayExcelAddDTO>
,用于监听和处理 Excel 的解析事件。主要功能包括解析表头、验证模板、批量处理数据等。
关键属性和方法
-
批量处理阈值
设定批量处理的阈值为 500 条记录,当累计到 500 条记录时进行一次批量处理。
private static final int BATCH_COUNT = 500; private List<HolidayExcelAddDTO> list = new ArrayList<>(BATCH_COUNT);
-
预期的列头
定义预期的列头,用于验证 Excel 模板是否正确。
private static final List<String> EXPECTED_HEADERS = List.of("节假日名称", "开始时间", "结束时间");
-
验证模板方法
在解析表头时调用
validateTemplate
方法,验证实际的列头是否与预期的列头一致。
@Override
public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
if (!isHeaderValid) {
validateTemplate(headMap, context);
isHeaderValid = true;
}
}
validateTemplate
方法的实现
该方法接收表头的映射和上下文作为参数,提取实际的列头,并与预期的列头进行比较。
private void validateTemplate(Map<Integer, CellData> headMap, AnalysisContext context) {
List<String> actualHeaders = headMap.values().stream()
.map(CellData::getStringValue)
.collect(Collectors.toList());
if (!EXPECTED_HEADERS.equals(actualHeaders)) {
throw new RuntimeException("Excel 模板不正确, 预期的列头: " + EXPECTED_HEADERS + ", 实际的列头: " + actualHeaders);
}
}
批量处理数据
当解析每一条数据时,将其加入到列表中。如果列表的大小达到批量处理的阈值,就进行批量处理。
@Override
public void invoke(HolidayExcelAddDTO holidayExcelAddDTO, AnalysisContext analysisContext) {
list.add(holidayExcelAddDTO);
if (list.size() >= BATCH_COUNT) {
importItemInfo(list);
list.clear();
}
}
完成解析后的处理
在解析完所有数据后,进行最后一次批量处理。
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
importItemInfo(list);
}
importItemInfo
方法的实现
该方法负责批量处理和保存数据。首先对数据进行验证,然后将其转换为 Holiday
对象,并批量保存到数据库中。
@Transactional(readOnly = false)
public void importItemInfo(List<HolidayExcelAddDTO> infoList) {
List<Holiday> holidayList = new ArrayList<>();
try {
for (HolidayExcelAddDTO holidayExcelAddDTO : infoList) {
if (holidayExcelAddDTO.getHolidayName() == null) {
throw new RuntimeException("节假日名称不能为空");
}
if (holidayExcelAddDTO.getBeginDate() == null) {
throw new RuntimeException("开始时间不能为空");
}
if (holidayExcelAddDTO.getEndDate() == null) {
throw new RuntimeException("结束时间不能为空");
}
Holiday holiday = new Holiday();
QueryWrapper<Holiday> queryWrapper = new QueryWrapper<>();
queryWrapper.select("holiday_id");
queryWrapper.eq("holiday_name", holidayExcelAddDTO.getHolidayName());
Holiday info = holidayService.getOne(queryWrapper);
if (!ObjectUtils.isEmpty(info)) {
throw new RuntimeException("节假日名称已存在");
}
holidayService.checkDateSize(holidayExcelAddDTO.getBeginDate(), holidayExcelAddDTO.getEndDate());
BeanUtils.copyProperties(holidayExcelAddDTO, holiday);
holiday.setBeginDate(LocalDate.parse(holidayExcelAddDTO.getBeginDate()));
holiday.setEndDate(LocalDate.parse(holidayExcelAddDTO.getEndDate()));
holiday.setCreateTime(LocalDateTime.now());
holidayList.add(holiday);
}
holidayService.saveBatch(holidayList);
} catch (Exception e) {
throw new RuntimeException("导入异常: " + e.getMessage(), e);
}
}
总结
通过 HolidayExcelListener
类,我们可以有效地验证 Excel 模板的正确性,并批量处理 Excel 数据。在实际应用中,可以根据具体需求进行扩展和优化。希望本文对大家在处理 Excel 导入时有所帮助。