diff --git a/src/main/java/com/pig4cloud/plugin/excel/ResponseExcelAutoConfiguration.java b/src/main/java/com/pig4cloud/plugin/excel/ResponseExcelAutoConfiguration.java index c40dd61..1e18e62 100644 --- a/src/main/java/com/pig4cloud/plugin/excel/ResponseExcelAutoConfiguration.java +++ b/src/main/java/com/pig4cloud/plugin/excel/ResponseExcelAutoConfiguration.java @@ -4,8 +4,6 @@ import com.pig4cloud.plugin.excel.aop.RequestExcelArgumentResolver; import com.pig4cloud.plugin.excel.aop.ResponseExcelReturnValueHandler; import com.pig4cloud.plugin.excel.config.ExcelConfigProperties; -import com.pig4cloud.plugin.excel.handler.DefaultDictDataProvider; -import com.pig4cloud.plugin.excel.handler.DictDataProvider; import com.pig4cloud.plugin.excel.kit.SpringContextKit; import com.pig4cloud.plugin.excel.processor.NameProcessor; import com.pig4cloud.plugin.excel.processor.NameSpelExpressionProcessor; @@ -87,10 +85,4 @@ public void setRequestExcelArgumentResolver() { requestMappingHandlerAdapter.setArgumentResolvers(resolverList); } - @Bean - @ConditionalOnMissingBean - public DictDataProvider dictDataProvider() { - return new DefaultDictDataProvider(); - } - } diff --git a/src/main/java/com/pig4cloud/plugin/excel/aop/RequestExcelArgumentResolver.java b/src/main/java/com/pig4cloud/plugin/excel/aop/RequestExcelArgumentResolver.java index 2dcd752..517e9f9 100644 --- a/src/main/java/com/pig4cloud/plugin/excel/aop/RequestExcelArgumentResolver.java +++ b/src/main/java/com/pig4cloud/plugin/excel/aop/RequestExcelArgumentResolver.java @@ -3,6 +3,7 @@ import com.alibaba.excel.EasyExcel; import com.pig4cloud.plugin.excel.annotation.RequestExcel; import com.pig4cloud.plugin.excel.converters.*; +import com.pig4cloud.plugin.excel.handler.DictCacheClearAnalysisEventListener; import com.pig4cloud.plugin.excel.handler.ListAnalysisEventListener; import jakarta.servlet.http.HttpServletRequest; import lombok.SneakyThrows; @@ -77,6 +78,7 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m .registerConverter(LongStringConverter.INSTANCE) .registerConverter(StringArrayConverter.INSTANCE) .registerConverter(DictTypeConvert.INSTANCE) + .registerReadListener(new DictCacheClearAnalysisEventListener()) .ignoreEmptyRow(requestExcel.ignoreEmptyRow()) .sheet() .headRowNumber(requestExcel.headRowNumber()) diff --git a/src/main/java/com/pig4cloud/plugin/excel/converters/DictTypeConvert.java b/src/main/java/com/pig4cloud/plugin/excel/converters/DictTypeConvert.java index 422916e..c5bd67d 100644 --- a/src/main/java/com/pig4cloud/plugin/excel/converters/DictTypeConvert.java +++ b/src/main/java/com/pig4cloud/plugin/excel/converters/DictTypeConvert.java @@ -11,8 +11,11 @@ import com.pig4cloud.plugin.excel.kit.SpringContextKit; import com.pig4cloud.plugin.excel.vo.DictEnum; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.MapUtils; import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; /** @@ -47,6 +50,8 @@ public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } + public static final Map cache = new HashMap<>(); + /** * 转换为 Java 数据 * @param cellData 单元格数据 @@ -58,7 +63,7 @@ public CellDataTypeEnum supportExcelTypeKey() { @Override public String convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { - if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + if (contentProperty == null) { return cellData.getStringValue(); } Field field = contentProperty.getField(); @@ -69,16 +74,28 @@ public String convertToJavaData(ReadCellData cellData, ExcelContentProperty c } if (declaredAnnotation.enums().length != 0) { - DictEnum[] enums = declaredAnnotation.enums()[0].getEnumConstants(); return DictEnum.getValueByLabel(enums, cellData.getStringValue()); } + DictEnum[] cacheEnums = cache.get(declaredAnnotation.value()); + if (cacheEnums != null) { + return DictEnum.getValueByLabel(cacheEnums, cellData.getStringValue()); + } + + Map beansOfType = SpringContextKit.getBeansOfType(DictDataProvider.class); + if (MapUtils.isEmpty(beansOfType)) { + log.error("请实现 DictDataProvider 接口,提供字典数据: https://www.yuque.com/pig4cloud/ogf9nv/pkxq8xqe9r6ax4fg"); + return cellData.getStringValue(); + } + DictDataProvider dictDataProvider = SpringContextKit.getBean(DictDataProvider.class); DictEnum[] dictEnums = dictDataProvider.getDict(declaredAnnotation.value()); if (dictEnums == null) { + log.warn("字典数据为空:{},自动字典转换失败", declaredAnnotation.value()); return cellData.getStringValue(); } + cache.put(declaredAnnotation.value(), dictEnums); return DictEnum.getValueByLabel(dictEnums, cellData.getStringValue()); } @@ -104,15 +121,31 @@ public WriteCellData convertToExcelData(String value, ExcelContentProper return new WriteCellData<>(DictEnum.getLabelByValue(enums, value)); } + DictEnum[] cacheEnums = cache.get(declaredAnnotation.value()); + if (cacheEnums != null) { + String labelByValue = DictEnum.getLabelByValue(cacheEnums, value); + if (labelByValue != null) { + return new WriteCellData<>(labelByValue); + } + } + + Map beansOfType = SpringContextKit.getBeansOfType(DictDataProvider.class); + if (MapUtils.isEmpty(beansOfType)) { + log.error("请实现 DictDataProvider 接口,提供字典数据: https://www.yuque.com/pig4cloud/ogf9nv/pkxq8xqe9r6ax4fg"); + return new WriteCellData<>(value); + } + DictDataProvider dictDataProvider = SpringContextKit.getBean(DictDataProvider.class); DictEnum[] dictEnums = dictDataProvider.getDict(declaredAnnotation.value()); if (dictEnums == null) { + log.warn("字典数据为空:{},自动字典转换失败", declaredAnnotation.value()); return new WriteCellData<>(value); } String labelByValue = DictEnum.getLabelByValue(dictEnums, value); if (labelByValue != null) { + cache.put(declaredAnnotation.value(), dictEnums); return new WriteCellData<>(labelByValue); } return new WriteCellData<>(value); diff --git a/src/main/java/com/pig4cloud/plugin/excel/handler/AbstractSheetWriteHandler.java b/src/main/java/com/pig4cloud/plugin/excel/handler/AbstractSheetWriteHandler.java index 3e99b84..a4f2e05 100644 --- a/src/main/java/com/pig4cloud/plugin/excel/handler/AbstractSheetWriteHandler.java +++ b/src/main/java/com/pig4cloud/plugin/excel/handler/AbstractSheetWriteHandler.java @@ -145,6 +145,9 @@ public ExcelWriter getExcelWriter(HttpServletResponse response, ResponseExcel re writerBuilder.registerConverter(BeanUtils.instantiateClass(clazz)); } + // 注册 Workbook 清空Dict处理器 + writerBuilder.registerWriteHandler(new DictCacheClearSheetWriteHandler()); + String templatePath = configProperties.getTemplatePath(); if (StringUtils.hasText(responseExcel.template())) { ClassPathResource classPathResource = new ClassPathResource( diff --git a/src/main/java/com/pig4cloud/plugin/excel/handler/DefaultDictDataProvider.java b/src/main/java/com/pig4cloud/plugin/excel/handler/DefaultDictDataProvider.java deleted file mode 100644 index 41d1745..0000000 --- a/src/main/java/com/pig4cloud/plugin/excel/handler/DefaultDictDataProvider.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.pig4cloud.plugin.excel.handler; - -/** - * @author lengleng - * @date 2024/8/30 - */ -public class DefaultDictDataProvider implements DictDataProvider { - -} diff --git a/src/main/java/com/pig4cloud/plugin/excel/handler/DictCacheClearAnalysisEventListener.java b/src/main/java/com/pig4cloud/plugin/excel/handler/DictCacheClearAnalysisEventListener.java new file mode 100644 index 0000000..b3e5b18 --- /dev/null +++ b/src/main/java/com/pig4cloud/plugin/excel/handler/DictCacheClearAnalysisEventListener.java @@ -0,0 +1,24 @@ +package com.pig4cloud.plugin.excel.handler; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.read.listener.ReadListener; +import com.pig4cloud.plugin.excel.converters.DictTypeConvert; + +/** + * dict cache clear analysis 事件监听器 + * + * @author lengleng + * @date 2024/08/31 + */ +public class DictCacheClearAnalysisEventListener implements ReadListener { + + @Override + public void invoke(Object o, AnalysisContext analysisContext) { + } + + @Override + public void doAfterAllAnalysed(AnalysisContext analysisContext) { + DictTypeConvert.cache.clear(); + } + +} diff --git a/src/main/java/com/pig4cloud/plugin/excel/handler/DictCacheClearSheetWriteHandler.java b/src/main/java/com/pig4cloud/plugin/excel/handler/DictCacheClearSheetWriteHandler.java new file mode 100644 index 0000000..b5b30b5 --- /dev/null +++ b/src/main/java/com/pig4cloud/plugin/excel/handler/DictCacheClearSheetWriteHandler.java @@ -0,0 +1,24 @@ +package com.pig4cloud.plugin.excel.handler; + +import com.alibaba.excel.write.handler.WorkbookWriteHandler; +import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext; +import com.pig4cloud.plugin.excel.converters.DictTypeConvert; + +/** + * dict 缓存清空 + * + * @author lengleng + * @date 2024/08/31 + */ +public class DictCacheClearSheetWriteHandler implements WorkbookWriteHandler { + + /** + * Called after all operations on the workbook have been completed + * @param context + */ + @Override + public void afterWorkbookDispose(WorkbookWriteHandlerContext context) { + DictTypeConvert.cache.clear(); + } + +} diff --git a/src/main/java/com/pig4cloud/plugin/excel/handler/DictDataProvider.java b/src/main/java/com/pig4cloud/plugin/excel/handler/DictDataProvider.java index 3a4a29e..9a9d3ad 100644 --- a/src/main/java/com/pig4cloud/plugin/excel/handler/DictDataProvider.java +++ b/src/main/java/com/pig4cloud/plugin/excel/handler/DictDataProvider.java @@ -1,10 +1,6 @@ package com.pig4cloud.plugin.excel.handler; import com.pig4cloud.plugin.excel.vo.DictEnum; -import org.apache.commons.lang3.ArrayUtils; - -import java.util.HashMap; -import java.util.Map; /** * dict 数据提供程序 @@ -14,68 +10,11 @@ */ public interface DictDataProvider { - static Map cache = new HashMap<>(); - - /** - * 获取缓存 - * @return {@link Map }<{@link String }, {@link DictEnum[] }> - */ - default Map getCache() { - return cache; - } - /** * 获取 dict * @param type 类型 * @return {@link DictEnum[] } */ - default DictEnum[] getDict(String type) { - return cache.get(type); - } - - /** - * 添加 dict - * @param type 类型 - * @param key key - * @param value value - */ - default void addDict(String type, String key, String value) { - // 1. 获取当前已有的 DictEnum 数组 - DictEnum[] existingEnums = cache.get(type); - - // 2. 创建新的 DictEnum 对象 - DictEnum newEnum = new DictEnum() { - @Override - public String getValue() { - return key; - } - - @Override - public String getLabel() { - return value; - } - }; - - // 3. 使用 ArrayUtils.add 将新元素添加到数组中 - DictEnum[] newEnums = ArrayUtils.add(existingEnums, newEnum); - - // 4. 将新数组放入 cache 中 - cache.put(type, newEnums); - } - - /** - * 删除 dict - * @param type 类型 - */ - default void delDict(String type) { - cache.remove(type); - } - - /** - * 重新加载 dict - */ - default void clear() { - cache.clear(); - } + DictEnum[] getDict(String type); } diff --git a/src/main/java/com/pig4cloud/plugin/excel/vo/DictEnum.java b/src/main/java/com/pig4cloud/plugin/excel/vo/DictEnum.java index 8424f46..707026e 100644 --- a/src/main/java/com/pig4cloud/plugin/excel/vo/DictEnum.java +++ b/src/main/java/com/pig4cloud/plugin/excel/vo/DictEnum.java @@ -1,6 +1,8 @@ package com.pig4cloud.plugin.excel.vo; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Objects; /** @@ -59,4 +61,43 @@ static String getValueByLabel(E[] enums, String label) { .orElse(null); } + /** + * 构建枚举类目 + * @param value 价值 + * @param label 标签 + * @return {@link DictEnum } + */ + static DictEnum of(String value, String label) { + return new DictEnum() { + @Override + public String getValue() { + return value; + } + + @Override + public String getLabel() { + return label; + } + }; + } + + static Builder builder() { + return new Builder(); + } + + class Builder { + + private final List items = new ArrayList<>(); + + public Builder add(String value, String label) { + items.add(DictEnum.of(value, label)); + return this; + } + + public DictEnum[] build() { + return items.toArray(new DictEnum[0]); + } + + } + } diff --git a/src/test/java/com/pig4cloud/plugin/excel/enums/DemoController.java b/src/test/java/com/pig4cloud/plugin/excel/enums/DemoController.java index 73e9147..505547f 100644 --- a/src/test/java/com/pig4cloud/plugin/excel/enums/DemoController.java +++ b/src/test/java/com/pig4cloud/plugin/excel/enums/DemoController.java @@ -48,7 +48,7 @@ public List test2() { } @PostMapping("/upload") - public void upload(@RequestExcel List dataList, BindingResult bindingResult) { + public void upload(@RequestExcel List dataList, BindingResult bindingResult) { // JSR 303 校验通用校验获取失败的数据 List errorMessageList = (List) bindingResult.getTarget(); } diff --git a/src/test/java/com/pig4cloud/plugin/excel/enums/DemoControllerTest.java b/src/test/java/com/pig4cloud/plugin/excel/enums/DemoControllerTest.java index 1453611..f717391 100644 --- a/src/test/java/com/pig4cloud/plugin/excel/enums/DemoControllerTest.java +++ b/src/test/java/com/pig4cloud/plugin/excel/enums/DemoControllerTest.java @@ -1,6 +1,5 @@ package com.pig4cloud.plugin.excel.enums; -import com.pig4cloud.plugin.excel.handler.DictDataProvider; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -56,18 +55,12 @@ void testFileDownloadAndSave() throws Exception { saveFileToResources("downloaded-example.xlsx", fileContent); } - @Autowired - private DictDataProvider dictDataProvider; - /** * 单元测试,写出excel 字段指定枚举 type * @throws Exception */ @Test void test2FileDownloadAndSave() throws Exception { - dictDataProvider.addDict("sex_type", "0", "男"); - dictDataProvider.addDict("sex_type", "1", "女"); - MvcResult result = mockMvc.perform(get("/demo/test2")).andExpect(status().isOk()).andReturn(); MockHttpServletResponse response = result.getResponse(); diff --git a/src/test/java/com/pig4cloud/plugin/excel/enums/DictDataProviderImpl.java b/src/test/java/com/pig4cloud/plugin/excel/enums/DictDataProviderImpl.java new file mode 100644 index 0000000..5b8a83a --- /dev/null +++ b/src/test/java/com/pig4cloud/plugin/excel/enums/DictDataProviderImpl.java @@ -0,0 +1,24 @@ +package com.pig4cloud.plugin.excel.enums; + +import com.pig4cloud.plugin.excel.handler.DictDataProvider; +import com.pig4cloud.plugin.excel.vo.DictEnum; + +/** + * @author lengleng + * @date 2024/8/31 + */ +// @Service +public class DictDataProviderImpl implements DictDataProvider { + + /** + * 获取 dict + * @param type 类型 + * @return {@link DictEnum[] } + */ + @Override + public DictEnum[] getDict(String type) { + // 查询数据库组装返回对应的字典数据 + return DictEnum.builder().add("1", "男").add("0", "女").build(); + } + +} diff --git a/src/test/java/com/pig4cloud/plugin/excel/enums/IndexOrNameData3.java b/src/test/java/com/pig4cloud/plugin/excel/enums/IndexOrNameData3.java index 81d8e85..1da4e98 100644 --- a/src/test/java/com/pig4cloud/plugin/excel/enums/IndexOrNameData3.java +++ b/src/test/java/com/pig4cloud/plugin/excel/enums/IndexOrNameData3.java @@ -17,7 +17,7 @@ public class IndexOrNameData3 { * 读取第一列 */ @ExcelProperty(value = "列1") - @DictTypeProperty("sex_type") + @DictTypeProperty("sex_txype") private String sex; } diff --git a/src/test/resources/tmp/enums.xlsx b/src/test/resources/tmp/enums.xlsx index d5a6b16..99333ce 100644 Binary files a/src/test/resources/tmp/enums.xlsx and b/src/test/resources/tmp/enums.xlsx differ