需求:实际开发中,同一下拉框可以选择任一单位,导入提供的Excel模板为统一单位,界面显示为统一固定单位.
前言
反射:对于运行时的类,我们可以知道它的所有属性和方法;对于运行时的对象,我们可以调用它的方法.
解决方案
解决方案:我们需要将单位进行入库存储,一个字段对应一个单位,导入时,将Excel模板的单位入库,最简单的方法是已知单位,直接设置值,但代码可读性降低,冗余量增多,本次推荐使用自定义注解获取导入字段对应的单位值,界面显示如果单位不为统一固定单位,则通过单位换算.
自定义注解Unit
// 生命周期
@Retention(RetentionPolicy.RUNTIME)
// 作用于属性
@Target(ElementType.FIELD)
public @interface Unit {
String value();
}
单位工具类
```public class UnitUtils {
// 实则是注解获取里面的值
public static String getUnitValue(Class<?> clazz, String fieldName) {
try {
// 获取指定字段
Field field = clazz.getDeclaredField(fieldName);
// 确保可以访问私有字段
field.setAccessible(true);
// 检查字段上是否有@Unit注解
if (field.isAnnotationPresent(Unit.class)) {
// 获取注解
Unit unit = field.getAnnotation(Unit.class);
// 返回注解的value值
return unit.value();
}
} catch (NoSuchFieldException e) {
// 处理异常,比如指定的字段名不存在
e.printStackTrace();
}
// 如果没有找到带有@Unit注解的字段,或者字段不存在,返回null或者抛出异常
return null;
}
导入数据DTO
@Data
public class CarbonIntensityDTO {
/** 长度 */
@ExcelProperty("长度")
@Unit("km")
private Double length ;
}
EasyExcel读取数据处理
public void importCarbonIntensity(MultipartFile file) {
try {
InputStream inputStream = file.getInputStream();
List<CarbonIntensityDTO> carbonDecompositionDTOList = EasyExcel.read(inputStream)
.head(CarbonIntensityDTO.class)
.sheet("Sheet1")
.headRowNumber(1)
.doReadSync();
List<CarbonIntensity> carbonIntensityList = Lists.newArrayList();
for(CarbonIntensityDTO carbonIntensityDTO : carbonDecompositionDTOList)
// 组装数据
CarbonIntensity carbonIntensity= new CarbonIntensity();
carbonIntensity.setLengthUnit(UnitUtils.getUnitValue(CarbonIntensityDTO.class,"length"));
carbonIntensityList.add(carbonIntensity);
}
// 调用新增接口
} catch (IOException e) {
e.printStackTrace();
}
}
单位统一工具类
@AllArgsConstructor
public class UnitConst {
private double scale;
private static final Map<String, UnitConst> units = Map.of(
"KM", new UnitConst(1000d),
"M", new UnitConst(1d)
);
private static UnitConst getUnit(String name) {
return units.get(name.toUpperCase());
}
public static double convert(double value, String fromUnitName, String toUnitName) {
UnitConst fromUnit = UnitConst.getUnit(fromUnitName);
UnitConst toUnit = UnitConst.getUnit(toUnitName);
if (fromUnit == null || toUnit == null) {
throw new BusinessException("不支持的单位");
}
return value * (fromUnit.scale / toUnit.scale);
}
}
ServiceImpl进行统一单位处理即可
小结
分析问题,解决问题,归纳整理,明确目的之后,直接实现即可.