mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 10:57:13 +08:00 
			
		
		
		
	新增:新增系统管理/部门管理/导出功能(引入 Easy Excel 依赖用于导出 Excel,详情可见 README 介绍。另请注意:测试导出功能时,前端需要关闭 mockjs,否则 responseType 会被 mockjs 设置为 '',导致导出的文件无法打开)
This commit is contained in:
		| @@ -22,6 +22,7 @@ import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import com.fasterxml.jackson.annotation.JsonIgnore; | ||||
|  | ||||
| /** | ||||
| @@ -45,11 +46,13 @@ public class BaseDetailVO extends BaseVO { | ||||
|      * 修改人 | ||||
|      */ | ||||
|     @Schema(description = "修改人") | ||||
|     @ExcelProperty(value = "修改人") | ||||
|     private String updateUserString; | ||||
|  | ||||
|     /** | ||||
|      * 修改时间 | ||||
|      */ | ||||
|     @Schema(description = "修改时间") | ||||
|     @ExcelProperty(value = "修改时间") | ||||
|     private LocalDateTime updateTime; | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,39 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.common.base; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.IEnum; | ||||
|  | ||||
| /** | ||||
|  * 枚举基类 | ||||
|  * | ||||
|  * @param <V> | ||||
|  *            value 类型 | ||||
|  * @param <D> | ||||
|  *            description 类型 | ||||
|  * @author Charles7c | ||||
|  * @since 2023/2/5 20:44 | ||||
|  */ | ||||
| public interface BaseEnum<V extends Serializable, D extends Serializable> extends IEnum<V> { | ||||
|  | ||||
|     /** | ||||
|      * 枚举描述 | ||||
|      */ | ||||
|     D getDescription(); | ||||
| } | ||||
| @@ -23,6 +23,7 @@ import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import com.fasterxml.jackson.annotation.JsonIgnore; | ||||
|  | ||||
| /** | ||||
| @@ -46,11 +47,13 @@ public class BaseVO implements Serializable { | ||||
|      * 创建人 | ||||
|      */ | ||||
|     @Schema(description = "创建人") | ||||
|     @ExcelProperty(value = "创建人") | ||||
|     private String createUserString; | ||||
|  | ||||
|     /** | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     @Schema(description = "创建时间") | ||||
|     @ExcelProperty(value = "创建时间") | ||||
|     private LocalDateTime createTime; | ||||
| } | ||||
|   | ||||
| @@ -86,6 +86,8 @@ public class WebMvcConfiguration implements WebMvcConfigurer { | ||||
|         corsProperties.getAllowedMethods().forEach(config::addAllowedMethod); | ||||
|         // 配置允许跨域的请求头 | ||||
|         corsProperties.getAllowedHeaders().forEach(config::addAllowedHeader); | ||||
|         // 配置允许跨域的响应头 | ||||
|         corsProperties.getExposedHeaders().forEach(config::addExposedHeader); | ||||
|  | ||||
|         // 添加映射路径,拦截一切请求 | ||||
|         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); | ||||
|   | ||||
| @@ -0,0 +1,92 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.common.config.easyexcel; | ||||
|  | ||||
| import com.alibaba.excel.converters.Converter; | ||||
| import com.alibaba.excel.enums.CellDataTypeEnum; | ||||
| import com.alibaba.excel.metadata.GlobalConfiguration; | ||||
| import com.alibaba.excel.metadata.data.ReadCellData; | ||||
| import com.alibaba.excel.metadata.data.WriteCellData; | ||||
| import com.alibaba.excel.metadata.property.ExcelContentProperty; | ||||
|  | ||||
| import cn.hutool.core.convert.Convert; | ||||
| import cn.hutool.core.util.ClassUtil; | ||||
| import cn.hutool.core.util.ObjectUtil; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseEnum; | ||||
|  | ||||
| /** | ||||
|  * Easy Excel 枚举基类转换器 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/2/5 19:29 | ||||
|  */ | ||||
| public class ExcelBaseEnumConverter implements Converter<BaseEnum<Integer, String>> { | ||||
|  | ||||
|     @Override | ||||
|     public Class<BaseEnum> supportJavaTypeKey() { | ||||
|         return BaseEnum.class; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public CellDataTypeEnum supportExcelTypeKey() { | ||||
|         return CellDataTypeEnum.STRING; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 转换为 Java 数据(读取 Excel) | ||||
|      */ | ||||
|     @Override | ||||
|     public BaseEnum convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, | ||||
|         GlobalConfiguration globalConfiguration) { | ||||
|         return this.getEnum(BaseEnum.class, Convert.toStr(cellData.getData())); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 转换为 Excel 数据(写入 Excel) | ||||
|      */ | ||||
|     @Override | ||||
|     public WriteCellData<String> convertToExcelData(BaseEnum<Integer, String> value, | ||||
|         ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { | ||||
|         if (ObjectUtil.isNull(value)) { | ||||
|             return new WriteCellData<>(""); | ||||
|         } | ||||
|         return new WriteCellData<>(value.getDescription()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 通过 value 获取枚举对象,获取不到时为 {@code null} | ||||
|      * | ||||
|      * @param enumType | ||||
|      *            枚举类型 | ||||
|      * @param description | ||||
|      *            描述 | ||||
|      * @return 对应枚举 ,获取不到时为 {@code null} | ||||
|      */ | ||||
|     private BaseEnum<Integer, String> getEnum(Class<?> enumType, String description) { | ||||
|         Object[] enumConstants = enumType.getEnumConstants(); | ||||
|         for (Object enumConstant : enumConstants) { | ||||
|             if (ClassUtil.isAssignable(BaseEnum.class, enumType)) { | ||||
|                 BaseEnum<Integer, String> baseEnum = (BaseEnum<Integer, String>)enumConstant; | ||||
|                 if (baseEnum.getDescription().equals(description)) { | ||||
|                     return baseEnum; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,79 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.common.config.easyexcel; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| import com.alibaba.excel.converters.Converter; | ||||
| import com.alibaba.excel.enums.CellDataTypeEnum; | ||||
| import com.alibaba.excel.metadata.GlobalConfiguration; | ||||
| import com.alibaba.excel.metadata.data.ReadCellData; | ||||
| import com.alibaba.excel.metadata.data.WriteCellData; | ||||
| import com.alibaba.excel.metadata.property.ExcelContentProperty; | ||||
|  | ||||
| import cn.hutool.core.convert.Convert; | ||||
| import cn.hutool.core.util.ObjectUtil; | ||||
|  | ||||
| /** | ||||
|  * Easy Excel 大数值转换器(Excel 中对长度超过 15 位的数值输入是有限制的,从 16 位开始无论录入什么数字均会变为 0,因此输入时只能以文本的形式进行录入) | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/2/5 19:29 | ||||
|  */ | ||||
| public class ExcelBigNumberConverter implements Converter<Long> { | ||||
|  | ||||
|     /** | ||||
|      * Excel 输入数值长度限制 | ||||
|      */ | ||||
|     private static final int MAX_LENGTH = 15; | ||||
|  | ||||
|     @Override | ||||
|     public Class<Long> supportJavaTypeKey() { | ||||
|         return Long.class; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public CellDataTypeEnum supportExcelTypeKey() { | ||||
|         return CellDataTypeEnum.STRING; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 转换为 Java 数据(读取 Excel) | ||||
|      */ | ||||
|     @Override | ||||
|     public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, | ||||
|         GlobalConfiguration globalConfiguration) { | ||||
|         return Convert.toLong(cellData.getData()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 转换为 Excel 数据(写入 Excel) | ||||
|      */ | ||||
|     @Override | ||||
|     public WriteCellData<Object> convertToExcelData(Long value, ExcelContentProperty contentProperty, | ||||
|         GlobalConfiguration globalConfiguration) { | ||||
|         if (ObjectUtil.isNotNull(value)) { | ||||
|             String str = Long.toString(value); | ||||
|             if (str.length() > MAX_LENGTH) { | ||||
|                 return new WriteCellData<>(str); | ||||
|             } | ||||
|         } | ||||
|         WriteCellData<Object> writeCellData = new WriteCellData<>(new BigDecimal(value)); | ||||
|         writeCellData.setType(CellDataTypeEnum.NUMBER); | ||||
|         return writeCellData; | ||||
|     } | ||||
| } | ||||
| @@ -19,7 +19,6 @@ package top.charles7c.cnadmin.common.config.jackson; | ||||
| import java.io.IOException; | ||||
| import java.lang.reflect.Field; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.annotation.IEnum; | ||||
| import com.fasterxml.jackson.core.*; | ||||
| import com.fasterxml.jackson.databind.DeserializationContext; | ||||
| import com.fasterxml.jackson.databind.JsonDeserializer; | ||||
| @@ -28,20 +27,23 @@ import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; | ||||
| import cn.hutool.core.util.ClassUtil; | ||||
| import cn.hutool.core.util.ReflectUtil; | ||||
| 
 | ||||
| import top.charles7c.cnadmin.common.base.BaseEnum; | ||||
| 
 | ||||
| /** | ||||
|  * 通用枚举接口 IEnum 反序列化器 | ||||
|  * 通用枚举基类 BaseEnum 反序列化器 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/1/8 13:56 | ||||
|  */ | ||||
| @JacksonStdImpl | ||||
| public class IEnumDeserializer extends JsonDeserializer<IEnum> { | ||||
| public class BaseEnumDeserializer extends JsonDeserializer<BaseEnum> { | ||||
| 
 | ||||
|     /** 静态实例 */ | ||||
|     public static final IEnumDeserializer SERIALIZER_INSTANCE = new IEnumDeserializer(); | ||||
|     public static final BaseEnumDeserializer SERIALIZER_INSTANCE = new BaseEnumDeserializer(); | ||||
| 
 | ||||
|     @Override | ||||
|     public IEnum deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { | ||||
|     public BaseEnum deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) | ||||
|         throws IOException { | ||||
|         Class<?> targetClass = jsonParser.getCurrentValue().getClass(); | ||||
|         String fieldName = jsonParser.getCurrentName(); | ||||
|         String value = jsonParser.getText(); | ||||
| @@ -49,7 +51,7 @@ public class IEnumDeserializer extends JsonDeserializer<IEnum> { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 通过某字段对应值获取枚举,获取不到时为 {@code null} | ||||
|      * 通过某字段对应值获取枚举实例,获取不到时为 {@code null} | ||||
|      * | ||||
|      * @param targetClass | ||||
|      *            目标类型 | ||||
| @@ -57,17 +59,17 @@ public class IEnumDeserializer extends JsonDeserializer<IEnum> { | ||||
|      *            字段值 | ||||
|      * @param fieldName | ||||
|      *            字段名 | ||||
|      * @return 对应枚举 ,获取不到时为 {@code null} | ||||
|      * @return 对应枚举实例 ,获取不到时为 {@code null} | ||||
|      */ | ||||
|     public IEnum getEnum(Class<?> targetClass, String value, String fieldName) { | ||||
|     private BaseEnum getEnum(Class<?> targetClass, String value, String fieldName) { | ||||
|         Field field = ReflectUtil.getField(targetClass, fieldName); | ||||
|         Class<?> fieldTypeClass = field.getType(); | ||||
|         Object[] enumConstants = fieldTypeClass.getEnumConstants(); | ||||
|         for (Object enumConstant : enumConstants) { | ||||
|             if (ClassUtil.isAssignable(IEnum.class, fieldTypeClass)) { | ||||
|                 IEnum iEnum = (IEnum)enumConstant; | ||||
|                 if (iEnum.getValue().equals(Integer.valueOf(value))) { | ||||
|                     return iEnum; | ||||
|             if (ClassUtil.isAssignable(BaseEnum.class, fieldTypeClass)) { | ||||
|                 BaseEnum baseEnum = (BaseEnum)enumConstant; | ||||
|                 if (baseEnum.getValue().equals(Integer.valueOf(value))) { | ||||
|                     return baseEnum; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -18,26 +18,27 @@ package top.charles7c.cnadmin.common.config.jackson; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.annotation.IEnum; | ||||
| import com.fasterxml.jackson.core.JsonGenerator; | ||||
| import com.fasterxml.jackson.databind.JsonSerializer; | ||||
| import com.fasterxml.jackson.databind.SerializerProvider; | ||||
| import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; | ||||
| 
 | ||||
| import top.charles7c.cnadmin.common.base.BaseEnum; | ||||
| 
 | ||||
| /** | ||||
|  * 通用枚举接口 IEnum 序列化器 | ||||
|  * 通用枚举接口 BaseEnum 序列化器 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/1/8 13:56 | ||||
|  */ | ||||
| @JacksonStdImpl | ||||
| public class IEnumSerializer extends JsonSerializer<IEnum> { | ||||
| public class BaseEnumSerializer extends JsonSerializer<BaseEnum> { | ||||
| 
 | ||||
|     /** 静态实例 */ | ||||
|     public static final IEnumSerializer SERIALIZER_INSTANCE = new IEnumSerializer(); | ||||
|     public static final BaseEnumSerializer SERIALIZER_INSTANCE = new BaseEnumSerializer(); | ||||
| 
 | ||||
|     @Override | ||||
|     public void serialize(IEnum value, JsonGenerator generator, SerializerProvider serializers) throws IOException { | ||||
|     public void serialize(BaseEnum value, JsonGenerator generator, SerializerProvider serializers) throws IOException { | ||||
|         generator.writeObject(value.getValue()); | ||||
|     } | ||||
| } | ||||
| @@ -31,7 +31,6 @@ import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.IEnum; | ||||
| import com.fasterxml.jackson.databind.*; | ||||
| import com.fasterxml.jackson.databind.module.SimpleModule; | ||||
| import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; | ||||
| @@ -43,6 +42,8 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; | ||||
| import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; | ||||
| import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseEnum; | ||||
|  | ||||
| /** | ||||
|  * Jackson 配置 | ||||
|  * | ||||
| @@ -89,15 +90,15 @@ public class JacksonConfiguration { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 针对通用枚举接口 IEnum 的序列化和反序列化 | ||||
|      * 针对枚举基类 BaseEnum 的序列化和反序列化 | ||||
|      */ | ||||
|     @Bean | ||||
|     public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { | ||||
|         SimpleModule simpleModule = new SimpleModule(); | ||||
|         simpleModule.addSerializer(IEnum.class, IEnumSerializer.SERIALIZER_INSTANCE); | ||||
|         simpleModule.addSerializer(BaseEnum.class, BaseEnumSerializer.SERIALIZER_INSTANCE); | ||||
|  | ||||
|         SimpleDeserializersWrapper deserializers = new SimpleDeserializersWrapper(); | ||||
|         deserializers.addDeserializer(IEnum.class, IEnumDeserializer.SERIALIZER_INSTANCE); | ||||
|         deserializers.addDeserializer(BaseEnum.class, BaseEnumDeserializer.SERIALIZER_INSTANCE); | ||||
|         simpleModule.setDeserializers(deserializers); | ||||
|  | ||||
|         ObjectMapper objectMapper = builder.createXmlMapper(false).build(); | ||||
|   | ||||
| @@ -38,7 +38,7 @@ import com.fasterxml.jackson.databind.type.ClassKey; | ||||
|  * 重写增强后:<br> | ||||
|  * 1. 同默认 1;<br> | ||||
|  * 2. 同默认 2;<br> | ||||
|  * 3. 如果也找不到 Enum 类型(所有枚举父类)的反序列化器,开始查找指定枚举类型的接口的反序列化器(例如:GenderEnum 枚举类型,则是找它的接口 IEnum 的反序列化器);<br> | ||||
|  * 3. 如果也找不到 Enum 类型(所有枚举父类)的反序列化器,开始查找指定枚举类型的接口的反序列化器(例如:GenderEnum 枚举类型,则是找它的接口 BaseEnum 的反序列化器);<br> | ||||
|  * 4. 同默认 3。 | ||||
|  * </p> | ||||
|  * | ||||
| @@ -56,7 +56,7 @@ public class SimpleDeserializersWrapper extends SimpleDeserializers { | ||||
|             return deser; | ||||
|         } | ||||
|  | ||||
|         // 重写增强:开始查找指定枚举类型的接口的反序列化器(例如:GenderEnum 枚举类型,则是找它的接口 IEnum 的反序列化器) | ||||
|         // 重写增强:开始查找指定枚举类型的接口的反序列化器(例如:GenderEnum 枚举类型,则是找它的接口 BaseEnum 的反序列化器) | ||||
|         for (Class<?> typeInterface : type.getInterfaces()) { | ||||
|             deser = this._classMappings.get(new ClassKey(typeInterface)); | ||||
|             if (deser != null) { | ||||
|   | ||||
| @@ -49,4 +49,9 @@ public class CorsProperties { | ||||
|      * 允许跨域的请求头 | ||||
|      */ | ||||
|     private List<String> allowedHeaders = new ArrayList<>(); | ||||
|  | ||||
|     /** | ||||
|      * 允许跨域的响应头 | ||||
|      */ | ||||
|     private List<String> exposedHeaders = new ArrayList<>(); | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,7 @@ package top.charles7c.cnadmin.common.enums; | ||||
| import lombok.Getter; | ||||
| import lombok.RequiredArgsConstructor; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.IEnum; | ||||
| import top.charles7c.cnadmin.common.base.BaseEnum; | ||||
|  | ||||
| /** | ||||
|  * 启用/禁用状态枚举 | ||||
| @@ -29,7 +29,7 @@ import com.baomidou.mybatisplus.annotation.IEnum; | ||||
|  */ | ||||
| @Getter | ||||
| @RequiredArgsConstructor | ||||
| public enum DisEnableStatusEnum implements IEnum<Integer> { | ||||
| public enum DisEnableStatusEnum implements BaseEnum<Integer, String> { | ||||
|  | ||||
|     /** 启用 */ | ||||
|     ENABLE(1, "启用"), | ||||
|   | ||||
| @@ -19,7 +19,7 @@ package top.charles7c.cnadmin.common.enums; | ||||
| import lombok.Getter; | ||||
| import lombok.RequiredArgsConstructor; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.IEnum; | ||||
| import top.charles7c.cnadmin.common.base.BaseEnum; | ||||
|  | ||||
| /** | ||||
|  * 性别枚举 | ||||
| @@ -29,7 +29,7 @@ import com.baomidou.mybatisplus.annotation.IEnum; | ||||
|  */ | ||||
| @Getter | ||||
| @RequiredArgsConstructor | ||||
| public enum GenderEnum implements IEnum<Integer> { | ||||
| public enum GenderEnum implements BaseEnum<Integer, String> { | ||||
|  | ||||
|     /** 未知 */ | ||||
|     UNKNOWN(0, "未知"), | ||||
|   | ||||
| @@ -0,0 +1,95 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.common.util; | ||||
|  | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
|  | ||||
| import lombok.AccessLevel; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
|  | ||||
| import com.alibaba.excel.EasyExcel; | ||||
| import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; | ||||
| import com.esotericsoftware.minlog.Log; | ||||
|  | ||||
| import cn.hutool.core.date.DateUtil; | ||||
| import cn.hutool.core.util.URLUtil; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.config.easyexcel.ExcelBigNumberConverter; | ||||
| import top.charles7c.cnadmin.common.exception.ServiceException; | ||||
|  | ||||
| /** | ||||
|  * Excel 工具类 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/2/5 18:00 | ||||
|  */ | ||||
| @Slf4j | ||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| public class ExcelUtils { | ||||
|  | ||||
|     /** | ||||
|      * 导出 | ||||
|      * | ||||
|      * @param list | ||||
|      *            导出数据集合 | ||||
|      * @param fileName | ||||
|      *            文件名 | ||||
|      * @param clazz | ||||
|      *            导出数据类型 | ||||
|      * @param response | ||||
|      *            响应对象 | ||||
|      */ | ||||
|     public static <V> void export(List<V> list, String fileName, Class<V> clazz, HttpServletResponse response) { | ||||
|         export(list, fileName, "Sheet1", clazz, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导出 | ||||
|      * | ||||
|      * @param list | ||||
|      *            导出数据集合 | ||||
|      * @param fileName | ||||
|      *            文件名 | ||||
|      * @param sheetName | ||||
|      *            工作表名称 | ||||
|      * @param clazz | ||||
|      *            导出数据类型 | ||||
|      * @param response | ||||
|      *            响应对象 | ||||
|      */ | ||||
|     public static <V> void export(List<V> list, String fileName, String sheetName, Class<V> clazz, | ||||
|         HttpServletResponse response) { | ||||
|         try { | ||||
|             fileName = String.format("%s_%s.xlsx", fileName, DateUtil.format(new Date(), "yyyyMMddHHmmss")); | ||||
|             fileName = URLUtil.encode(fileName); | ||||
|             response.setHeader("Content-disposition", "attachment;filename=" + fileName); | ||||
|             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); | ||||
|             EasyExcel.write(response.getOutputStream(), clazz).autoCloseStream(false) | ||||
|                 // 自动适配宽度 | ||||
|                 .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) | ||||
|                 // 自动转换大数值 | ||||
|                 .registerConverter(new ExcelBigNumberConverter()).sheet(sheetName).doWrite(list); | ||||
|         } catch (Exception e) { | ||||
|             Log.error("Export excel occurred an error.", e); | ||||
|             throw new ServiceException("导出 Excel 出现错误"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -91,6 +91,17 @@ public class ExceptionUtils { | ||||
|         return exToDefault(supplier, null, exConsumer); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 如果有异常,返回空字符串 | ||||
|      * | ||||
|      * @param exSupplier | ||||
|      *            可能会出现异常的方法执行 | ||||
|      * @return / | ||||
|      */ | ||||
|     public static String exToBlank(ExSupplier<String> exSupplier) { | ||||
|         return exToDefault(exSupplier, ""); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 如果有异常,返回默认值 | ||||
|      * | ||||
|   | ||||
		Reference in New Issue
	
	Block a user