处理Excel中数据格式的验证和清理
一、数据格式验证
(一)使用框架自带的验证功能(以EasyExcel为例)
- 表头验证
- 在EasyExcel中,可以通过自定义监听器来验证表头格式。监听器中的
invokeHeadMap
方法会在解析表头时被调用。 - 例如,假设我们有一个实体类
User
,对应的Excel文件中应该有“姓名”、“年龄”和“邮箱”这几个表头列。
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import java.util.Map; public class UserExcelListener extends AnalysisEventListener<User> { @Override public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext analysisContext) { boolean hasName = false; boolean hasAge = false; boolean hasEmail = false; for (String head : headMap.values()) { if ("姓名".equals(head)) { hasName = true; } else if ("年龄".equals(head)) { hasAge = true; } else if ("邮箱".equals(head)) { hasEmail = true; } } if (!hasName ||!hasAge ||!hasEmail) { throw new RuntimeException("表头格式不正确,请确保包含'姓名'、'年龄'和'邮箱'列"); } } @Override public void invoke(User user, AnalysisContext analysisContext) { // 处理每一行数据 } @Override public void doAfterAllAnalyzed(AnalysisContext analysisContext) { // 数据全部解析完成后的操作 } }
- 在EasyExcel中,可以通过自定义监听器来验证表头格式。监听器中的
- 数据类型验证(基于注解和转换器)
- 使用
@ExcelProperty
注解和数据转换器- 对于基本数据类型,如将Excel中的数据转换为Java中的
Integer
类型。如果Excel中的数据可能存在格式问题(如包含非数字字符),可以使用数据转换器。 - 例如,创建一个整数数据转换器:
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataType; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; import java.util.regex.Pattern; public class IntegerConverter implements Converter<Integer> { private static final Pattern INTEGER_PATTERN = Pattern.compile("^\\d+$"); @Override public Class<?> supportJavaTypeKey() { return Integer.class; } @Override public CellDataType supportExcelTypeKey() { return CellDataType.STRING; } @Override public Integer convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception { String value = cellData.getStringValue(); if (INTEGER_PATTERN.matcher(value).matches()) { return Integer.parseInt(value); } else { throw new RuntimeException("数据格式错误,应为整数: " + value); } } @Override public CellData<?> convertToExcelData(Integer integer, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception { return new CellData<>(String.valueOf(integer)); } }
- 在实体类中的
@ExcelProperty
注解中使用这个转换器:
import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; @Data public class User { @ExcelProperty(value = "年龄", converter = IntegerConverter.class) private Integer age; }
- 对于基本数据类型,如将Excel中的数据转换为Java中的
- 使用
(二)自定义验证逻辑
- 基于正则表达式的验证
- 对于一些文本格式的数据,如邮箱地址,可以使用正则表达式进行验证。
- 在监听器的
invoke
方法中对每一行数据进行验证。 - 例如:
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import java.util.regex.Pattern; public class UserExcelListener extends AnalysisEventListener<User> { private static final Pattern EMAIL_PATTERN = Pattern.compile("^[a - zA - Z0 - 9_.+-]+@[a - zA - Z0 - 9 -]+\\.[a - zA - Z0 - 9 -]+$"); @Override public void invoke(User user, AnalysisContext analysisContext) { if (user.getEmail()!= null &&!EMAIL_PATTERN.matcher(user.getEmail()).matches()) { throw new RuntimeException("邮箱格式错误: " + user.getEmail()); } // 其他数据处理 } @Override public void doAfterAllAnalyzed(AnalysisContext analysisContext) { // 数据全部解析完成后的操作 } }
二、数据清理
(一)去除空白数据
- 在监听器中处理
- 在监听器的
invoke
方法中,可以检查每个字段是否为空白(对于字符串类型),如果是空白且业务上允许,可以将其设置为null
或者默认值。 - 例如:
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; public class UserExcelListener extends AnalysisEventListener<User> { @Override public void invoke(User user, AnalysisContext analysisContext) { if (user.getName()!= null && user.getName().trim().isEmpty()) { user.setName(null); } // 其他数据处理 } @Override public void doAfterAllAnalyzed(AnalysisContext analysisContext) { // 数据全部解析完成后的操作 } }
- 在监听器的
(二)替换特殊字符
- 使用字符串处理方法
- 如果Excel中的数据包含一些特殊字符(如制表符、换行符等),在监听器的
invoke
方法中可以使用字符串的replace
方法进行替换。 - 例如,假设要去除字符串中的换行符:
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; public class UserExcelListener extends AnalysisEventListener<User> { @Override public void invoke(User user, AnalysisContext analysisContext) { if (user.getComment()!= null) { user.setComment(user.getComment().replace("\n", "")); } // 其他数据处理 } @Override public void doAfterAllAnalyzed(AnalysisContext analysisContext) { // 数据全部解析完成后的操作 } }
- 如果Excel中的数据包含一些特殊字符(如制表符、换行符等),在监听器的