背景
springBoot 使用easy-poi导出excel的时候对于使用字典的字段,需要使用replace将值和value按规定列出来,但既然使用了字典,那我们原则上就是希望直接用户自己修改字典值,之后所有功能依旧使用;若我们导出将所有值列出来则与初衷相违背,因此,我们可以使用切面动态修改replace值,上代码。
代码实现
1. 自定义注解
/**
1. @Description 导出自定义注解
2. @Author wk
3. @Date 2021/10/11 10:36
**/
@Documented
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelReplace {
Class value() default Object.class;
}
2. 定义切面
/**
1. @Description 导出切面
2. @Author wk
3. @Date 2021/10/11 9:33
**/
@Aspect
@Component
public class ExcelReplaceAspect {
// 字典注入,按需引用
@Autowired
private StackDictTypeService stackDictTypeService;
// 切点
@Pointcut("@annotation(io.ctc.utils.annotations.ExcelReplace)")
public void excelReplacePointcut(){
}
// 执行之前的逻辑
@Before("excelReplacePointcut()")
public void around(JoinPoint point) throws NoSuchFieldException, IllegalAccessException {
// 字典map
Map<String, List<StackDictData>> dictMap = stackDictTypeService.getAllList().stream().collect(Collectors.toMap(StackDictType::getDictType, StackDictType::getDataList));
// 获取自定义注解配置的value---实体类
MethodSignature signature = (MethodSignature) point.getSignature();
ExcelReplace annotation = signature.getMethod().getAnnotation(ExcelReplace.class);
// 获取对应实体
Class exportClass = annotation.value();
// 通过反射获取实体的所有字段
Field[] declaredFields = exportClass.getDeclaredFields();
for (Field field : declaredFields) {
// 判断该字段是否带有@Excel注解
Excel excel = field.getAnnotation(Excel.class);
if(excel != null){
// 获取excel注解的所有参数值
InvocationHandler invocationHandler = Proxy.getInvocationHandler(excel);
Field value = invocationHandler.getClass().getDeclaredField("memberValues");
value.setAccessible(true);
Map<String, Object> memberValues = (Map<String, Object>) value.get(invocationHandler);
// 判断是否设置了有效的字典项
if(StringUtils.isNotBlank(excel.dict()) && dictMap.get(excel.dict()) != null){
List<String> list = dictMap.get(excel.dict()).stream().map(data -> data.getDictLabel() + "_" + data.getDictValue()).collect(Collectors.toList());
// 添加空
list.add("_null");
memberValues.put("replace", list.toArray(new String[0]));
}
}
}
}
}
3.实体使用
/**
* 所属域
*/
@Excel(name = "所属域",dict = "dictDomain")
private String dictDomain;
4. 导出方法
@ExcelReplace(PhycomputersInfoExportDto.class)
@PostMapping("export")
public void export(@RequestBody Map<String, Object> params, HttpServletResponse response) {
// 您的导出
}