From 36ea8358daea3f6a8a1729a56bd55c4d73b1f406 Mon Sep 17 00:00:00 2001 From: lijiayao <3377164217@qq.com> Date: Mon, 18 Dec 2023 21:29:55 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=80=E5=94=AE=E6=97=A5=E5=BF=97+=E9=94=80?= =?UTF-8?q?=E5=94=AE=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2-4270-9baa-25c339a705a3_商品销售统计.xlsx | Bin 0 -> 4285 bytes ...d-4815-9ef9-1e3a228e1865_商品销售统计.xlsx | Bin 0 -> 4271 bytes ...f-457f-a384-046615f74e02_商品销售统计.xlsx | Bin 0 -> 4282 bytes ...6-4d83-ac6f-eb4830c940d2_商品销售统计.xlsx | Bin 0 -> 4271 bytes bwie-common/pom.xml | 24 + .../main/java/com/bwie/common/pojo/Sell.java | 114 +++ .../java/com/bwie/common/pojo/VO/VOSell.java | 31 + .../java/com/bwie/common/result/Result.java | 24 + .../com/bwie/common/utils/WebMvcConfig.java | 22 + .../common/utils/core/date/DateUtils.java | 137 +++ .../utils/core/reflect/ReflectUtils.java | 386 ++++++++ .../common/utils/core/spring/SpringUtils.java | 106 +++ .../common/utils/core/text/CharsetKit.java | 78 ++ .../bwie/common/utils/core/text/Convert.java | 818 ++++++++++++++++ .../com/bwie/common/utils/poi/ExcelUtil.java | 874 ++++++++++++++++++ .../common/utils/poi/annotation/Excel.java | 122 +++ .../common/utils/poi/annotation/Excels.java | 18 + .../utils/poi/exception/PoiException.java | 27 + .../common/utils/poi3/CustomCellStyle.java | 79 ++ .../bwie/common/utils/poi3/EasyExcelUtil.java | 208 +++++ bwie-gateway/pom.xml | 2 - .../com/bwie/gateway/filters/AuthFilter.java | 170 ++-- bwie-models/bwie-sell/.gitignore | 38 + bwie-models/bwie-sell/pom.xml | 90 ++ .../java/com/bwie/sell/SellApplication.java | 16 + .../bwie/sell/controller/SellController.java | 73 ++ .../java/com/bwie/sell/mapper/SellMapper.java | 28 + .../com/bwie/sell/service/SellService.java | 29 + .../sell/service/impl/SellServiceImpl.java | 68 ++ .../java/com/bwie/sell/util/FastUtil.java | 55 ++ .../bwie/sell/util/poi3/CustomCellStyle.java | 76 ++ .../bwie/sell/util/poi3/EasyExcelUtil.java | 193 ++++ .../src/main/resources/bootstrap.yml | 58 ++ .../src/main/resources/mapper/SellMapper.xml | 59 ++ .../src/main/resources/bootstrap.yml | 2 +- bwie-models/pom.xml | 1 + ...3-4314-a2e6-ea20f916ad3c_商品销售统计.xlsx | Bin 0 -> 4282 bytes 37 files changed, 3938 insertions(+), 88 deletions(-) create mode 100644 79b1fe79-9272-4270-9baa-25c339a705a3_商品销售统计.xlsx create mode 100644 a543d9e9-238d-4815-9ef9-1e3a228e1865_商品销售统计.xlsx create mode 100644 af94f4ed-edcf-457f-a384-046615f74e02_商品销售统计.xlsx create mode 100644 bad59ad9-68d6-4d83-ac6f-eb4830c940d2_商品销售统计.xlsx create mode 100644 bwie-common/src/main/java/com/bwie/common/pojo/Sell.java create mode 100644 bwie-common/src/main/java/com/bwie/common/pojo/VO/VOSell.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/WebMvcConfig.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/core/date/DateUtils.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/core/reflect/ReflectUtils.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/core/spring/SpringUtils.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/core/text/CharsetKit.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/core/text/Convert.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/poi/ExcelUtil.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/poi/annotation/Excel.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/poi/annotation/Excels.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/poi/exception/PoiException.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/poi3/CustomCellStyle.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/poi3/EasyExcelUtil.java create mode 100644 bwie-models/bwie-sell/.gitignore create mode 100644 bwie-models/bwie-sell/pom.xml create mode 100644 bwie-models/bwie-sell/src/main/java/com/bwie/sell/SellApplication.java create mode 100644 bwie-models/bwie-sell/src/main/java/com/bwie/sell/controller/SellController.java create mode 100644 bwie-models/bwie-sell/src/main/java/com/bwie/sell/mapper/SellMapper.java create mode 100644 bwie-models/bwie-sell/src/main/java/com/bwie/sell/service/SellService.java create mode 100644 bwie-models/bwie-sell/src/main/java/com/bwie/sell/service/impl/SellServiceImpl.java create mode 100644 bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/FastUtil.java create mode 100644 bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/poi3/CustomCellStyle.java create mode 100644 bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/poi3/EasyExcelUtil.java create mode 100644 bwie-models/bwie-sell/src/main/resources/bootstrap.yml create mode 100644 bwie-models/bwie-sell/src/main/resources/mapper/SellMapper.xml create mode 100644 f95ab62a-c2f3-4314-a2e6-ea20f916ad3c_商品销售统计.xlsx diff --git a/79b1fe79-9272-4270-9baa-25c339a705a3_商品销售统计.xlsx b/79b1fe79-9272-4270-9baa-25c339a705a3_商品销售统计.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..fe5f6ae7f73b4967e222c46b4882e13d870c1cce GIT binary patch literal 4285 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 literal 0 HcmV?d00001 diff --git a/af94f4ed-edcf-457f-a384-046615f74e02_商品销售统计.xlsx b/af94f4ed-edcf-457f-a384-046615f74e02_商品销售统计.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..d6ba08544be6243c1a565659c5d16c657542bc9b GIT binary patch literal 4282 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 C>jq;0 literal 0 HcmV?d00001 diff --git a/bad59ad9-68d6-4d83-ac6f-eb4830c940d2_商品销售统计.xlsx b/bad59ad9-68d6-4d83-ac6f-eb4830c940d2_商品销售统计.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e0fe6aa75233d3d5d5bfc3bff641fe3be7bdb045 GIT binary patch literal 4271 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 literal 0 HcmV?d00001 diff --git a/bwie-common/pom.xml b/bwie-common/pom.xml index 0e5576b..3d0fe36 100644 --- a/bwie-common/pom.xml +++ b/bwie-common/pom.xml @@ -132,6 +132,30 @@ 9.3.7.v20160115 + + + + org.apache.poi + poi-ooxml + 3.17 + + + org.apache.poi + poi-ooxml-schemas + 3.17 + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + com.alibaba + easyexcel + 2.2.7 + + diff --git a/bwie-common/src/main/java/com/bwie/common/pojo/Sell.java b/bwie-common/src/main/java/com/bwie/common/pojo/Sell.java new file mode 100644 index 0000000..219a8e9 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/pojo/Sell.java @@ -0,0 +1,114 @@ +package com.bwie.common.pojo; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.bwie.common.utils.poi.annotation.Excel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * @author 86175 + * 记录销售记录 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Sell { + + /** + * 销售编号 + */ + @ExcelIgnore + private Integer sellId; + /** + * 商品编号 + */ + @ExcelIgnore + private Integer shopId; + /** + * 卖出的时间 + */ + @Excel(name = "卖出商品的时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date sellTime; + /** + * 用户 + */ + @ExcelIgnore + private Integer userId; + /** + * 设备表 + */ + @ExcelIgnore + private Integer facilityId; + /** + * 设备类型 + */ + @Excel(name = "设备类型") + private String facilityType; + /** + * 设备地址 + */ + @Excel(name = "设备地址") + private String facilitySite; + /** + * 补货员工 + */ + @Excel(name = "补货员工") + private Integer replenishmentUserId; + /** + * 维修员工 + */ + @Excel(name = "维修员工") + private Integer maintainUserId; + /** + * 设备状态 + */ + @Excel(name = "设备状态") + private String facilityStatic; + /** + * 删除状态 + */ + @ExcelIgnore + private Integer delId; + /** + * 商品名称 + */ + @Excel(name = "商品名称") + private String shopName; + /** + * 商品价格 + */ + @Excel(name = "商品价格") + private Double shopPrice; + /** + * 类型编号 + */ + @ExcelIgnore + private Integer typeId; + /** + * 商品类型 + */ + @Excel(name = "商品类型") + private String typeName; + /** + * 用户名 + */ + @Excel(name = "用户名") + public String userName; + /** + * 手机号 + */ + @Excel(name = "手机号") + public String phone; + /** + * 邮箱 + */ + @Excel(name = "邮箱") + public String email; + + +} diff --git a/bwie-common/src/main/java/com/bwie/common/pojo/VO/VOSell.java b/bwie-common/src/main/java/com/bwie/common/pojo/VO/VOSell.java new file mode 100644 index 0000000..e19e94f --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/pojo/VO/VOSell.java @@ -0,0 +1,31 @@ +package com.bwie.common.pojo.VO; + +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * 传参 + * @author 86175 + */ +@Data +public class VOSell { + + /** + * 商品编号 + */ + private Integer shopId; + /** + * 卖出的时间 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date sellTime; + /** + * 用户 + */ + private Integer userId; + + + +} diff --git a/bwie-common/src/main/java/com/bwie/common/result/Result.java b/bwie-common/src/main/java/com/bwie/common/result/Result.java index 30b1e73..45f75ff 100644 --- a/bwie-common/src/main/java/com/bwie/common/result/Result.java +++ b/bwie-common/src/main/java/com/bwie/common/result/Result.java @@ -73,4 +73,28 @@ public class Result implements Serializable { apiResult.setMsg(msg); return apiResult; } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } } diff --git a/bwie-common/src/main/java/com/bwie/common/utils/WebMvcConfig.java b/bwie-common/src/main/java/com/bwie/common/utils/WebMvcConfig.java new file mode 100644 index 0000000..a5f29e3 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/WebMvcConfig.java @@ -0,0 +1,22 @@ +//package com.bwie.common.utils; +// +//import org.springframework.context.annotation.Configuration; +//import org.springframework.http.converter.HttpMessageConverter; +//import org.springframework.stereotype.Component; +//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +// +//import java.util.List; +// +///** +// * @author 86175 +// * 消息转换器 +// */ +//@Configuration +//public class WebMvcConfig implements WebMvcConfigurer { +// +// @Override +// public void configureMessageConverters(List> converters) { +//// converters.add(new ExcelMessageConverter()); +// } +// +//} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/core/date/DateUtils.java b/bwie-common/src/main/java/com/bwie/common/utils/core/date/DateUtils.java new file mode 100644 index 0000000..8d60608 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/core/date/DateUtils.java @@ -0,0 +1,137 @@ +package com.bwie.common.utils.core.date; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.io.File; +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 时间工具类 + * + * @author markGuo + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Date getNowDate() { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + * + * @return String + */ + public static String getDate() { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) { + try { + return new SimpleDateFormat(format).parse(ts); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy"+File.separator+"MM"+ File.separator +"dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateTime() { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) { + if (str == null) { + return null; + } + try { + return parseDate(str.toString(), parsePatterns); + } catch (ParseException e) { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算两个时间差 + */ + public static String getDatePoor(Date endDate, Date nowDate) { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - nowDate.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/core/reflect/ReflectUtils.java b/bwie-common/src/main/java/com/bwie/common/utils/core/reflect/ReflectUtils.java new file mode 100644 index 0000000..80e4426 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/core/reflect/ReflectUtils.java @@ -0,0 +1,386 @@ +package com.bwie.common.utils.core.reflect; + +import com.bwie.common.utils.core.date.DateUtils; +import com.bwie.common.utils.core.text.Convert; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.*; +import java.util.Date; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + * @author markGuo + */ +@SuppressWarnings("rawtypes") +public class ReflectUtils { + /** + * set方法前缀 + */ + private static final String SETTER_PREFIX = "set"; + + /** + * get方法前缀 + */ + private static final String GETTER_PREFIX = "get"; + + /** + * CGLIB 类分隔符 + */ + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + /** + * 日志 + */ + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); + + /** + * 调用Getter方法. + * 支持多级,如:对象名.对象名.方法 + * @param obj + * @param propertyName + * @param + * @return + */ + @SuppressWarnings("unchecked") + public static E invokeGetter(Object obj, String propertyName) { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")) { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return (E) object; + } + + /** + * 调用Setter方法, 仅匹配方法名。 + * 支持多级,如:对象名.对象名.方法 + * @param obj + * @param propertyName + * @param value + * @param + */ + public static void invokeSetter(Object obj, String propertyName, E value) { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i = 0; i < names.length; i++) { + if (i < names.length - 1) { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } else { + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); + invokeMethodByName(object, setterMethodName, new Object[] { value }); + } + } + } + + /** + * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. + * @param obj + * @param fieldName + * @param + * @return + */ + @SuppressWarnings("unchecked") + public static E getFieldValue(final Object obj, final String fieldName) { + Field field = getAccessibleField(obj, fieldName); + if (field == null) { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return null; + } + E result = null; + try { + result = (E) field.get(obj); + } catch (IllegalAccessException e) { + logger.error("不可能抛出的异常{}", e.getMessage()); + } + return result; + } + + /** + * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. + * @param obj + * @param fieldName + * @param value + * @param + */ + public static void setFieldValue(final Object obj, final String fieldName, final E value) { + Field field = getAccessibleField(obj, fieldName); + if (field == null) { + // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return; + } + try { + field.set(obj, value); + } catch (IllegalAccessException e) { + logger.error("不可能抛出的异常: {}", e.getMessage()); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符. + * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. + * 同时匹配方法名+参数类型, + * @param obj + * @param methodName + * @param parameterTypes + * @param args + * @param + * @return + */ + @SuppressWarnings("unchecked") + public static E invokeMethod(final Object obj, final String methodName, final Class[] parameterTypes, + final Object[] args) { + if (obj == null || methodName == null) { + return null; + } + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try { + return (E) method.invoke(obj, args); + } catch (Exception e) { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + * @param obj + * @param methodName + * @param args + * @param + * @return + */ + @SuppressWarnings("unchecked") + public static E invokeMethodByName(final Object obj, final String methodName, final Object[] args) { + Method method = getAccessibleMethodByName(obj, methodName, args.length); + if (method == null) { + // 如果为空不报错,直接返回空。 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try { + // 类型转换(将参数数据类型转换为目标方法参数类型) + Class[] cs = method.getParameterTypes(); + for (int i = 0; i < cs.length; i++) { + if (args[i] != null && !args[i].getClass().equals(cs[i])) { + if (cs[i] == String.class) { + args[i] = Convert.toStr(args[i]); + if (StringUtils.endsWith((String) args[i], ".0")) { + args[i] = StringUtils.substringBefore((String) args[i], ".0"); + } + } else if (cs[i] == Integer.class) { + args[i] = Convert.toInt(args[i]); + } else if (cs[i] == Long.class) { + args[i] = Convert.toLong(args[i]); + } else if (cs[i] == Double.class) { + args[i] = Convert.toDouble(args[i]); + } else if (cs[i] == Float.class) { + args[i] = Convert.toFloat(args[i]); + } else if (cs[i] == Date.class) { + if (args[i] instanceof String) { + args[i] = DateUtils.parseDate(args[i]); + } + } + } + } + return (E) method.invoke(obj, args); + } catch (Exception e) { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * @param obj + * @param fieldName + * @return + */ + public static Field getAccessibleField(final Object obj, final String fieldName) { + // 为空不报错。直接返回 null + if (obj == null) { + return null; + } + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { + try { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } + catch (NoSuchFieldException e) { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + * @param obj + * @param methodName + * @param parameterTypes + * @return + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) { + // 为空不报错。直接返回 null + if (obj == null) { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + try { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } catch (NoSuchMethodException e) { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + * @param obj + * @param methodName + * @param argsNum + * @return + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) { + // 为空不报错。直接返回 null + if (obj == null) { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + * @param method + */ + public static void makeAccessible(Method method) { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + * @param field + */ + public static void makeAccessible(Field field) { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + * @param clazz + * @param + * @return + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + * @param clazz + * @param index + * @return + */ + public static Class getClassGenricType(final Class clazz, final int index) { + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) { + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) { + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) { + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + /** + * 通过实例化对象获取反射对象 + * @param instance + * @return + */ + public static Class getUserClass(Object instance) { + if (instance == null) { + throw new RuntimeException("Instance must not be null"); + } + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) { + return superClass; + } + } + return clazz; + + } + + /** + * 将反射时的checked exception转换为unchecked exception. + * @param msg + * @param e + * @return + */ + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) { + return new IllegalArgumentException(msg, e); + } else if (e instanceof InvocationTargetException) { + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); + } + return new RuntimeException(msg, e); + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/core/spring/SpringUtils.java b/bwie-common/src/main/java/com/bwie/common/utils/core/spring/SpringUtils.java new file mode 100644 index 0000000..68a2ef6 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/core/spring/SpringUtils.java @@ -0,0 +1,106 @@ +package com.bwie.common.utils.core.spring; + +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.stereotype.Component; + +/** + * spring工具类 方便在非spring管理环境中获取bean + * + * @author markGuo + */ +@Component +public final class SpringUtils implements BeanFactoryPostProcessor +{ + /** Spring应用上下文环境 */ + private static ConfigurableListableBeanFactory beanFactory; + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + SpringUtils.beanFactory = beanFactory; + } + + /** + * 获取对象 + * + * @param name + * @return Object 一个以所给名字注册的bean的实例 + * @throws BeansException + * + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) throws BeansException { + return (T) beanFactory.getBean(name); + } + + /** + * 获取类型为requiredType的对象 + * + * @param clz + * @return + * @throws BeansException + * + */ + public static T getBean(Class clz) throws BeansException { + T result = beanFactory.getBean(clz); + return result; + } + + /** + * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true + * + * @param name + * @return boolean + */ + public static boolean containsBean(String name) { + return beanFactory.containsBean(name); + } + + /** + * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) + * + * @param name + * @return boolean + * @throws NoSuchBeanDefinitionException + * + */ + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { + return beanFactory.isSingleton(name); + } + + /** + * @param name + * @return Class 注册对象的类型 + * @throws NoSuchBeanDefinitionException + * + */ + public static Class getType(String name) throws NoSuchBeanDefinitionException { + return beanFactory.getType(name); + } + + /** + * 如果给定的bean名字在bean定义中有别名,则返回这些别名 + * + * @param name + * @return + * @throws NoSuchBeanDefinitionException + * + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { + return beanFactory.getAliases(name); + } + + /** + * 获取aop代理对象 + * + * @param invoker + * @return + */ + @SuppressWarnings("unchecked") + public static T getAopProxy(T invoker) { + return (T) AopContext.currentProxy(); + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/core/text/CharsetKit.java b/bwie-common/src/main/java/com/bwie/common/utils/core/text/CharsetKit.java new file mode 100644 index 0000000..eca5c63 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/core/text/CharsetKit.java @@ -0,0 +1,78 @@ +package com.bwie.common.utils.core.text; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + * 字符集工具类 + * + * @author markGuo + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, String srcCharset, String destCharset) { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) { + if (null == srcCharset) { + srcCharset = StandardCharsets.ISO_8859_1; + } + if (null == destCharset) { + srcCharset = StandardCharsets.UTF_8; + } + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 系统字符集编码 + */ + public static String systemCharset() { + return Charset.defaultCharset().name(); + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/core/text/Convert.java b/bwie-common/src/main/java/com/bwie/common/utils/core/text/Convert.java new file mode 100644 index 0000000..e3a6698 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/core/text/Convert.java @@ -0,0 +1,818 @@ +package com.bwie.common.utils.core.text; + + +import org.apache.commons.lang3.StringUtils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; + +/** + * 类型转换器 + * + * @author markGuo + */ +public class Convert { + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static String toStr(Object value, String defaultValue) { + if (null == value) { + return defaultValue; + } + if (value instanceof String) { + return (String) value; + } + return value.toString(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Character toChar(Object value, Character defaultValue) { + if (null == value) { + return defaultValue; + } + if (value instanceof Character) { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Byte toByte(Object value, Byte defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof Byte) { + return (Byte) value; + }else if (value instanceof Number) { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + return Byte.parseByte(valueStr); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Short toShort(Object value, Short defaultValue) { + if (value == null) { + return defaultValue; + }else if (value instanceof Short) { + return (Short) value; + } else if (value instanceof Number) { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + return Short.parseShort(valueStr.trim()); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Number toNumber(Object value, Number defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof Number) { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + return NumberFormat.getInstance().parse(valueStr); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Integer toInt(Object value, Integer defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof Integer) { + return (Integer) value; + } else if (value instanceof Number) { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + return Integer.parseInt(valueStr.trim()); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) { + if (StringUtils.isEmpty(str)) { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为Long数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String split, String str) { + if (StringUtils.isEmpty(str)) { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) { + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Long toLong(Object value, Long defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof Long) { + return (Long) value; + } else if (value instanceof Number) { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).longValue(); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Double toDouble(Object value, Double defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof Double) { + return (Double) value; + } else if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).doubleValue(); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Float toFloat(Object value, Float defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof Float) { + return (Float) value; + } else if (value instanceof Number) { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + return Float.parseFloat(valueStr.trim()); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Boolean toBool(Object value, Boolean defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof Boolean) { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) { + case "true": + return true; + case "false": + return false; + case "yes": + return true; + case "ok": + return true; + case "no": + return false; + case "1": + return true; + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value, E defaultValue) { + if (value == null) { + return defaultValue; + } else if (clazz.isAssignableFrom(value.getClass())) { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + return Enum.valueOf(clazz, valueStr); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof BigInteger) { + return (BigInteger) value; + } else if (value instanceof Long) { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + return new BigInteger(valueStr); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) { + if (value == null) { + return defaultValue; + } else if (value instanceof BigDecimal) { + return (BigDecimal) value; + } else if (value instanceof Long) { + return new BigDecimal((Long) value); + } else if (value instanceof Double) { + return new BigDecimal((Double) value); + } else if (value instanceof Integer) { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) { + return defaultValue; + } + try { + return new BigDecimal(valueStr); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(Object obj, Charset charset) { + if (null == obj) { + return null; + } else if (obj instanceof String) { + return (String) obj; + } else if (obj instanceof byte[] || obj instanceof Byte[]) { + return str(obj, charset); + } else if (obj instanceof ByteBuffer) { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @param bytes byte数组 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(byte[] bytes, String charset) { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + public static String str(byte[] data, Charset charset) { + if (data == null) { + return null; + } else if (null == charset) { + return new String(data); + } + return new String(data, charset); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, String charset) { + if (data == null) { + return null; + } + return str(data, Charset.forName(charset)); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, Charset charset) { + if (null == charset) { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 全角半角转换 + /** + * 半角转全角 + * + * @param input String. + * @return 全角字符串. + */ + public static String toSBC(String input) { + return toSBC(input, null); + } + + /** + * 半角转全角 + * + * @param input String + * @param notConvertSet 不替换的字符集合 + * @return 全角字符串. + */ + public static String toSBC(String input, Set notConvertSet) { + char c[] = input.toCharArray(); + for (int i = 0; i < c.length; i++) { + if (null != notConvertSet && notConvertSet.contains(c[i])) { + // 跳过不替换的字符 + continue; + } else if (c[i] == ' ') { + c[i] = '\u3000'; + } else if (c[i] < '\177') { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 全角转半角 + * + * @param input String. + * @return 半角字符串 + */ + public static String toDBC(String input) { + return toDBC(input, null); + } + + /** + * 替换全角为半角 + * + * @param text 文本 + * @param notConvertSet 不替换的字符集合 + * @return 替换后的字符 + */ + public static String toDBC(String text, Set notConvertSet) { + char c[] = text.toCharArray(); + for (int i = 0; i < c.length; i++) { + if (null != notConvertSet && notConvertSet.contains(c[i])) { + // 跳过不替换的字符 + continue; + } else if (c[i] == '\u3000') { + c[i] = ' '; + } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { + c[i] = (char) (c[i] - 65248); + } + } + return new String(c); + } + + /** + * 数字金额大写转换 先写个完整的然后将如零拾替换成零 + * + * @param n 数字 + * @return 中文大写数字 + */ + public static String digitUppercase(double n) { + String[] fraction = { "角", "分" }; + String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; + String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } }; + + String head = n < 0 ? "负" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) { + s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); + } + if (s.length() < 1) { + s = "整"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; + } + return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/poi/ExcelUtil.java b/bwie-common/src/main/java/com/bwie/common/utils/poi/ExcelUtil.java new file mode 100644 index 0000000..22407e9 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/poi/ExcelUtil.java @@ -0,0 +1,874 @@ +package com.bwie.common.utils.poi; + + +import com.bwie.common.utils.core.date.DateUtils; +import com.bwie.common.utils.core.reflect.ReflectUtils; +import com.bwie.common.utils.core.spring.SpringUtils; +import com.bwie.common.utils.core.text.Convert; +import com.bwie.common.utils.poi.annotation.Excel; +import com.bwie.common.utils.poi.annotation.Excel.Type; +import com.bwie.common.utils.poi.annotation.Excels; +import com.bwie.common.utils.poi.exception.PoiException; +import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; + +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.*; + +/** + * Excel相关处理 + * + * @author + */ +@Log4j2 +public class ExcelUtil +{ + + /** + * 手动设置表头模板 + */ + private static final String[] TEMPLATE_COLUMNS = { + "员工编号","员工姓名","员工性别","员工年龄","员工薪资","薪资范围" + }; + /** + * 手动设置数据类型 0数字 1字符串 + */ + private static final Integer[] DATA_TYPE_COLUMNS = { + 0,1,1,0,0,1 + }; + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 实体对象 + */ + public Class clazz; + + public ExcelUtil(Class clazz) { + this.clazz = clazz; + } + + public void init(List list, String sheetName, Type type) { + if (list == null) { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + createExcelField(); + createWorkbook(); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) throws Exception { + return importExcel(StringUtils.EMPTY, is); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is) throws Exception { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + Sheet sheet = null; + if (StringUtils.isNotEmpty(sheetName)) { + // 如果指定sheet名,则取指定sheet中的内容. + sheet = wb.getSheet(sheetName); + } else { + // 如果传入的sheet名不存在则默认指向第1个sheet. + sheet = wb.getSheetAt(0); + } + + if (sheet == null) { + throw new IOException("文件sheet不存在"); + } + + int rows = sheet.getPhysicalNumberOfRows(); + + if (rows > 0) { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(0); + + /** + * 检查导入的模板是否正确 + */ + if (!checkTemplate(heard)) { + System.out.println("模板错误,请检查列名是否正确"); + return null; + } + + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) { + Cell cell = heard.getCell(i); + if (cell != null) { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } + else { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + Field[] allFields = clazz.getDeclaredFields(); + // 定义一个map用于存放列的序号和field. + Map fieldsMap = new HashMap(); + for (int col = 0; col < allFields.length; col++) { + Field field = allFields[col]; + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) { + // 设置类的私有字段属性可访问. + field.setAccessible(true); + Integer column = cellMap.get(attr.name()); + fieldsMap.put(column, field); + } + } + + /** + * 定义一个收集错误信息的集合 + */ + List errorMessages = new ArrayList<>(); + + for (int i = 1; i < rows; i++) { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + + /** + * 检查导入数据是否正确 + */ + int nums = row.getPhysicalNumberOfCells(); + for (int j = 0; j < nums; j++) { + if (!checkDataType(row,j)){ + String errorMessage = String.format("第%d行%d列数据类型错误", i + 1,j+1); + errorMessages.add(errorMessage); + } + } + + + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) { + if (entry.getKey() == null){ + continue; + } + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = fieldsMap.get(entry.getKey()); + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) { + val = StringUtils.substringBefore(s, ".0"); + } else { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) { + val = DateUtils.parseDateToStr(dateFormat, (Date) val); + } else { + val = Convert.toStr(val); + } + } + } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) { + val = Convert.toInt(val); + } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) { + val = Convert.toLong(val); + } else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) { + val = Convert.toDouble(val); + } else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) { + val = Convert.toFloat(val); + } else if (BigDecimal.class == fieldType) { + val = Convert.toBigDecimal(val); + } else if (Date.class == fieldType) { + if (val instanceof String) { + val = DateUtils.parseDate(val); + } else if (val instanceof Double) { + val = DateUtil.getJavaDate((Double) val); + } + } + if (fieldType != null) { + Excel attr = field.getAnnotation(Excel.class); + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) { + propertyName = field.getName() + "." + attr.targetAttr(); + } else if (StringUtils.isNotEmpty(attr.readConverterExp())) { + val = reverseByExp(String.valueOf(val), attr.readConverterExp()); + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + //打印所有错误信息 + System.out.println("-------------------------错误信息如下:--------------------------"); + for (String errorMessage : errorMessages) { + System.out.println(errorMessage); + } + } + + return list; + } + + /** + * 检查导入的模板 + * @param heard + * @return + */ + private boolean checkTemplate(Row heard) { + int numberOfCells = heard.getPhysicalNumberOfCells(); + if (numberOfCells!=TEMPLATE_COLUMNS.length){ + return false; + } + for (int i = 0; i < numberOfCells; i++) { + if (!heard.getCell(i).getStringCellValue().equals(TEMPLATE_COLUMNS[i])){ + return false; + } + } + return true; + } + + /** + * 设置数据类型做判断 + * @param row + * @return + */ + private boolean checkDataType(Row row,Integer column) { + try { + //设置数据类型 + + if (1==DATA_TYPE_COLUMNS[column]){ + String stringCellValue = row.getCell(column).getStringCellValue(); + }else { + /*String numericCellValue = row.getCell(column).getStringCellValue(); + double v = Double.parseDouble(numericCellValue);*/ + double numericCellValue = row.getCell(column).getNumericCellValue(); + } + return true; + } catch (Exception e) { + return false; + } + } + + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + * @throws IOException + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName){ + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, Type.EXPORT); + writeSheet(); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response){ + try{ + wb.write(response.getOutputStream()); + } catch (Exception e){ + log.error("导出Excel异常{}", e.getMessage()); + } finally { + IOUtils.closeQuietly(wb); + } + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public String exportExcel(List list, String sheetName) { + this.init(list, sheetName, Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public String importTemplateExcel(String sheetName) { + this.init(null, sheetName, Type.IMPORT); + return exportExcel(); + } + + /** + * 写入sheet数据 + */ + public void writeSheet(){ + // 取出一共有多少个sheet. + double sheetNo = Math.ceil(list.size() / sheetSize); + for (int index = 0; index <= sheetNo; index++) { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(0); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) { + Excel excel = (Excel) os[1]; + this.createCell(excel, row, column++); + } + if (Type.EXPORT.equals(type)) { + fillExcelData(index, row); + } + } + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public String exportExcel() { + OutputStream out = null; + try { + writeSheet(); + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return filename; + } catch (Exception e) { + log.error("导出Excel异常{}", e.getMessage()); + throw new PoiException("导出Excel失败,请联系管理员!"); + } finally { + try { + if (wb != null) { + wb.close(); + } + if (out != null) { + out.close(); + } + } catch (IOException e1) { + e1.printStackTrace(); + } + + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + public void fillExcelData(int index, Row row) { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + for (int i = startNo; i < endNo; i++) { + row = sheet.createRow(i + 1 - startNo); + // 得到导出对象. + T vo = (T) list.get(i); + int column = 0; + for (Object[] os : fields) { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(IndexedColors.WHITE.getIndex()); + style.setFont(headerFont); + styles.put("header", style); + + return styles; + } + + /** + * 创建单元格 + */ + public Cell createCell(Excel attr, Row row, int column) { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get("header")); + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) { + if (Excel.ColumnType.STRING == attr.cellType()) { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(value == null ? attr.defaultValue() : value + attr.suffix()); + } else if (Excel.ColumnType.NUMERIC == attr.cellType()) { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(Integer.parseInt(value + "")); + } + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) { + if (attr.name().indexOf("注:") >= 0) { + sheet.setColumnWidth(column, 6000); + } else { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + row.setHeight((short) (attr.height() * 20)); + } + // 如果设置了提示信息则鼠标放上去提示. + if (StringUtils.isNotEmpty(attr.prompt())) { + // 这里默认设了2-101列提示. + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); + } + // 如果设置了combo属性则本列只能选择不能输入 + if (attr.combo().length > 0) { + // 这里默认设了2-101列只能选择不能输入. + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) { + Cell cell = null; + try { + // 设置行高 + row.setHeight((short) (attr.height() * 20)); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) { + // 创建cell + cell = row.createCell(column); + cell.setCellStyle(styles.get("data")); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + //时间类型格式化 + String dateFormat = attr.dateFormat(); + //读取表达式 + String readConverterExp = attr.readConverterExp(); + //分隔符 + String splitStr = attr.splitStr(); + //反射对象 + Class invokeClass = attr.invokeClass(); + //反射方法名称 + String invokeMethod = attr.invokeMethod(); + if (StringUtils.isNotEmpty(dateFormat) && value != null) { + cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value)); + } else if (StringUtils.isNotEmpty(readConverterExp) && value != null) { + // 判断是否有分隔符 + if (StringUtils.isNotEmpty(splitStr)){ + StringBuilder cellValue = new StringBuilder(); + String valueStr = String.valueOf(value); + String[] valueStrSplit = valueStr.split(splitStr); + int valueStrSplitLength = valueStrSplit.length; + for (int i = 0; ; i++) { + cellValue.append(convertByExp(valueStrSplit[i], readConverterExp)); + if (i == valueStrSplitLength-1){ + break; + } + cellValue.append(","); + } + cell.setCellValue(cellValue.toString()); + } else { + cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp)); + } + + } + // 判断是否需要取值 + else if((!invokeClass.getName().equals(String.class.getName())) && StringUtils.isNotEmpty(invokeMethod)){ + Object bean = SpringUtils.getBean(invokeClass); + Method thisMethod = null; + Method[] methods = invokeClass.getMethods(); + for (Method method : methods) { + if (method.getName().equals(invokeMethod)){ + thisMethod = method; + continue; + } + } + cell.setCellValue(thisMethod.invoke(bean,value).toString()); + } else { + // 设置列类型 + setCellVo(value, attr, cell); + } + } + } catch (Exception e) { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示 + * + * @param sheet 表单 + * @param promptTitle 提示标题 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + dataValidation.createPromptBox(promptTitle, promptContent); + dataValidation.setShowPromptBox(true); + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框. + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + * @return 设置好的sheet. + */ + public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) { + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } else { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @return 解析后值 + * @throws Exception + */ + public static String convertByExp(String propertyValue, String converterExp) throws Exception { + try { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) { + String[] itemArray = item.split("="); + if (itemArray[0].equals(propertyValue)) { + return itemArray[1]; + } + } + } catch (Exception e) { + throw e; + } + return propertyValue; + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @return 解析后值 + * @throws Exception + */ + public static String reverseByExp(String propertyValue, String converterExp) throws Exception { + try { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) { + String[] itemArray = item.split("="); + if (itemArray[1].equals(propertyValue)) { + return itemArray[0]; + } + } + } catch (Exception e) { + throw e; + } + return propertyValue; + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) { + filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) { + String downloadPath = System.getProperty("user.dir") + File.separator + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) { + String target = excel.targetAttr(); + if (target.indexOf(".") > -1) { + String[] targets = target.split("[.]"); + for (String name : targets) { + o = getValue(o, name); + } + } else { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception { + if (StringUtils.isNotEmpty(name)) { + Class clazz = o.getClass(); + String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); + Method method = clazz.getMethod(methodName); + o = method.invoke(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() { + this.fields = new ArrayList<>(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) { + putToField(field, field.getAnnotation(Excel.class)); + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel excel : excels) { + putToField(field, excel); + } + } + } + } + + /** + * 放到字段集合中 + */ + private void putToField(Field field, Excel attr) { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) { + this.fields.add(new Object[] { field, attr }); + } + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() { + this.wb = new SXSSFWorkbook(500); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(double sheetNo, int index) { + this.sheet = wb.createSheet(); + this.styles = createStyles(wb); + // 设置工作表的名称. + if (sheetNo == 0) { + wb.setSheetName(index, sheetName); + } else { + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) { + if (row == null) { + return row; + } + Object val = ""; + try { + Cell cell = row.getCell(column); + if (cell != null) { + if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA) { + val = cell.getNumericCellValue(); + if (HSSFDateUtil.isCellDateFormatted(cell)) { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } else { + if ((Double) val % 1 > 0) { + val = new DecimalFormat("0.00").format(val); + } else { + val = new DecimalFormat("0").format(val); + } + } + } else if (cell.getCellTypeEnum() == CellType.STRING) { + val = cell.getStringCellValue(); + } else if (cell.getCellTypeEnum() == CellType.BOOLEAN) { + val = cell.getBooleanCellValue(); + } else if (cell.getCellTypeEnum() == CellType.ERROR) { + val = cell.getErrorCellValue(); + } + + } + } catch (Exception e) { + return val; + } + return val; + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/poi/annotation/Excel.java b/bwie-common/src/main/java/com/bwie/common/utils/poi/annotation/Excel.java new file mode 100644 index 0000000..c2b29b9 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/poi/annotation/Excel.java @@ -0,0 +1,122 @@ +package com.bwie.common.utils.poi.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义导出Excel数据注解 + * + * @author + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符 + */ + public String splitStr() default ""; + + /** + * 可执行的反射方法值为1个 + */ + public String invokeMethod() default ""; + + /** + * 可执行的反射类 从SpringIoc容器当中取值 + */ + public Class invokeClass() default String.class; + + /** + * 导出类型(0数字 1字符串) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出时在excel中每个列的高度 单位为字符 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽 单位为字符 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) { + this.value = value; + } + + public int value() { + return this.value; + } + } + + public enum ColumnType { + NUMERIC(0), STRING(1); + private final int value; + + ColumnType(int value) { + this.value = value; + } + + public int value() { + return this.value; + } + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/poi/annotation/Excels.java b/bwie-common/src/main/java/com/bwie/common/utils/poi/annotation/Excels.java new file mode 100644 index 0000000..9760459 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/poi/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.bwie.common.utils.poi.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + Excel[] value(); +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/poi/exception/PoiException.java b/bwie-common/src/main/java/com/bwie/common/utils/poi/exception/PoiException.java new file mode 100644 index 0000000..a08fe9c --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/poi/exception/PoiException.java @@ -0,0 +1,27 @@ +package com.bwie.common.utils.poi.exception; + +/** + * 业务异常 + * + * @author + */ +public class PoiException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + protected final String message; + + public PoiException(String message) { + this.message = message; + } + + public PoiException(String message, Throwable e) { + super(message, e); + this.message = message; + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/poi3/CustomCellStyle.java b/bwie-common/src/main/java/com/bwie/common/utils/poi3/CustomCellStyle.java new file mode 100644 index 0000000..c3f36b1 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/poi3/CustomCellStyle.java @@ -0,0 +1,79 @@ +package com.bwie.common.utils.poi3; + +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import org.apache.poi.ss.usermodel.*; + +import java.util.List; + +public class CustomCellStyle implements CellWriteHandler { + + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + + + } + + @Override + public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + //获取工作簿 + Workbook workbook = writeSheetHolder.getSheet().getWorkbook(); + + //获取单元格样式 + CellStyle cellStyle = workbook.createCellStyle(); + + //判断非首行 + if(!isHead && cell.getColumnIndex()==2){ + + String stringCellValue = cell.getStringCellValue(); + + //double numericCellValue = cell.getNumericCellValue(); + if("女".equals(stringCellValue)){ + //填充背景色 + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + cellStyle.setFillForegroundColor(IndexedColors.RED.index); + + //设置字体 + Font font = workbook.createFont(); + font.setBold(true); + font.setColor(IndexedColors.BLACK.getIndex()); + cellStyle.setFont(font); + } + + + }else{} + + //设置边框 + cellStyle.setBorderTop(BorderStyle.THIN); + cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); + + cellStyle.setBorderRight(BorderStyle.THIN); + cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); + + cellStyle.setBorderBottom(BorderStyle.THIN); + cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); + + cellStyle.setBorderLeft(BorderStyle.THIN); + cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); + + cell.setCellStyle(cellStyle); + + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/poi3/EasyExcelUtil.java b/bwie-common/src/main/java/com/bwie/common/utils/poi3/EasyExcelUtil.java new file mode 100644 index 0000000..d609f86 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/poi3/EasyExcelUtil.java @@ -0,0 +1,208 @@ +//package com.bwie.common.utils.poi3; +// +//import com.alibaba.excel.EasyExcel; +//import com.alibaba.excel.ExcelWriter; +//import com.alibaba.excel.metadata.Head; +//import com.alibaba.excel.support.ExcelTypeEnum; +//import com.alibaba.excel.util.CollectionUtils; +//import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; +//import com.alibaba.excel.write.merge.AbstractMergeStrategy; +//import com.alibaba.excel.write.metadata.WriteSheet; +//import com.alibaba.excel.write.metadata.style.WriteCellStyle; +//import com.alibaba.excel.write.metadata.style.WriteFont; +//import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +//import lombok.Data; +//import lombok.NoArgsConstructor; +//import org.apache.poi.ss.formula.functions.T; +//import org.apache.poi.ss.usermodel.Cell; +//import org.apache.poi.ss.usermodel.FillPatternType; +//import org.apache.poi.ss.usermodel.IndexedColors; +//import org.apache.poi.ss.usermodel.Sheet; +//import org.apache.poi.ss.util.CellRangeAddress; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Component; +// +//import javax.security.sasl.SaslServer; +//import javax.servlet.http.HttpServletResponse; +//import java.io.IOException; +//import java.io.UnsupportedEncodingException; +//import java.net.URLEncoder; +//import java.util.ArrayList; +//import java.util.Arrays; +//import java.util.List; +//import java.util.stream.Collectors; +// +//// 自定义合并策略 该类继承了AbstractMergeStrategy抽象合并策略,需要重写merge()方法 +//@Component +//@Data +//@NoArgsConstructor +//public class EasyExcelUtil extends AbstractMergeStrategy { +// +// +// @Autowired +// private SaslServer saslServer; +// +// /** +// * 分组,每几行合并一次 +// */ +// private List exportFieldGroupCountList; +// +// /** +// * 目标合并列index +// */ +// private Integer targetColumnIndex; +// +// // 需要开始合并单元格的首行index +// private Integer rowIndex; +// +// // exportDataList为待合并目标列的值 +// public EasyExcelUtil(List exportDataList, Integer targetColumnIndex) { +// this.exportFieldGroupCountList = getGroupCountList(exportDataList); +// this.targetColumnIndex = targetColumnIndex; +// } +// +// +// @Override +// protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { +// +// if (null == rowIndex) { +// rowIndex = cell.getRowIndex(); +// } +// // 仅从首行以及目标列的单元格开始合并,忽略其他 +// if (cell.getRowIndex() == rowIndex && cell.getColumnIndex() == targetColumnIndex) { +// mergeGroupColumn(sheet); +// } +// } +// +// private void mergeGroupColumn(Sheet sheet) { +// int rowCount = rowIndex; +// for (Integer count : exportFieldGroupCountList) { +// if(count == 1) { +// rowCount += count; +// continue ; +// } +// // 合并单元格 +// CellRangeAddress cellRangeAddress = new CellRangeAddress(rowCount, rowCount + count - 1, targetColumnIndex, targetColumnIndex); +// sheet.addMergedRegionUnsafe(cellRangeAddress); +// rowCount += count; +// } +// } +// +// // 该方法将目标列根据值是否相同连续可合并,存储可合并的行数 +// private List getGroupCountList(List exportDataList){ +// if (CollectionUtils.isEmpty(exportDataList)) { +// return new ArrayList<>(); +// } +// +// List groupCountList = new ArrayList<>(); +// int count = 1; +// +// for (int i = 1; i < exportDataList.size(); i++) { +// if (exportDataList.get(i).equals(exportDataList.get(i - 1))) { +// count++; +// } else { +// groupCountList.add(count); +// count = 1; +// } +// } +// // 处理完最后一条后 +// groupCountList.add(count); +// return groupCountList; +// } +// +// +// // 修改WriteSheet的代码如下 +// public void writeExcel(HttpServletResponse response,String fileName,Integer mergeIndex,String firstTitle,String [] secondTile,Integer sheetSize) { +// // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman +// response.setContentType("application/vnd.ms-excel"); +// response.setCharacterEncoding("utf-8"); +// // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 +// try { +// String name = URLEncoder.encode(fileName, "UTF-8"); +// +// response.setHeader("Content-disposition", "attachment;filename=" + name + ".xlsx"); +// +// List> heads = new ArrayList<>(); +// for (int i = 0; i < secondTile.length; i++) { +// heads.add(Arrays.asList(firstTitle,secondTile[i])); +// } +// +// +// +// +// ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()) +// .build(); +// +// List studentListAll = studentService.findStudentListAll(); +// //select * from t_student limit 0,2 1 (pageNum-1)*pageSize +// //select * from t_student limit 2,2 2 +// //select * from t_student limit 4,2 3 +// //select * from t_student limit 6,2 4 +// +// Integer count = studentListAll.size(); +// Integer sheets = (int)Math.ceil((double)count/sheetSize); +// +// +// +// for (int i = 0; i < sheets; i++) { +// PageInfo studentList = studentService.findStudentList(i + 1, sheetSize); +// WriteSheet sheet1 = EasyExcel.writerSheet(i, "模版"+(i+1)).head(Student.class) +// .head(heads).registerWriteHandler(new EasyExcelUtil(studentList.getList().stream().map(Student::getSex).collect(Collectors.toList()), mergeIndex)) +// .registerWriteHandler(new CustomCellStyle()).build(); +// +// +// excelWriter.write(studentList.getList(),sheet1); +// } +// +// +// excelWriter.finish(); +// response.flushBuffer(); +// +// +// +// +// +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// +// } +// +// +// // 修改WriteSheet的代码如下 +// public void writeExcel(HttpServletResponse response,String fileName, List list,String [] secondTile) { +// // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman +// response.setContentType("application/vnd.ms-excel"); +// response.setCharacterEncoding("utf-8"); +// // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 +// try { +// String name = URLEncoder.encode(fileName, "UTF-8"); +// +// response.setHeader("Content-disposition", "attachment;filename=" + name + ".xlsx"); +// +// List> heads = new ArrayList<>(); +// for (int i = 0; i < secondTile.length; i++) { +// heads.add(Arrays.asList(secondTile[i])); +// } +// +// +// EasyExcel.write(response.getOutputStream(),Student.class).sheet("模板").head(Student.class) +// .head(heads) +// //.registerWriteHandler(new EasyExcelUtil(list.stream().map(Student::getName).collect(Collectors.toList()), mergeIndex)) +// //.registerWriteHandler(new CustomCellStyle()) //设置单元格颜色样式 +// .doWrite(list); +// +// +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// +// } +// +// +// +//} \ No newline at end of file diff --git a/bwie-gateway/pom.xml b/bwie-gateway/pom.xml index 3c4d2fc..3015468 100644 --- a/bwie-gateway/pom.xml +++ b/bwie-gateway/pom.xml @@ -17,7 +17,6 @@ UTF-8 - @@ -42,5 +41,4 @@ - diff --git a/bwie-gateway/src/main/java/com/bwie/gateway/filters/AuthFilter.java b/bwie-gateway/src/main/java/com/bwie/gateway/filters/AuthFilter.java index 483141b..b570369 100644 --- a/bwie-gateway/src/main/java/com/bwie/gateway/filters/AuthFilter.java +++ b/bwie-gateway/src/main/java/com/bwie/gateway/filters/AuthFilter.java @@ -1,85 +1,85 @@ -package com.bwie.gateway.filters; - -import com.bwie.common.constants.TokenConstants; -import com.bwie.common.utils.JwtUtils; -import com.bwie.common.utils.StringUtils; -import com.bwie.gateway.config.IgnoreWhiteConfig; -import com.bwie.gateway.utils.GatewayUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.core.Ordered; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.http.HttpStatus; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.stereotype.Component; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; - -import java.util.List; - -/** - * @ClassName: - * @Description: 鉴权过滤器 - * @Author: zhuwenqiang - * @Date: 2023/8/18 - */ -@Component -public class AuthFilter implements GlobalFilter, Ordered { - - @Autowired - private IgnoreWhiteConfig ignoreWhiteConfig; - - @Autowired - private RedisTemplate redisTemplate; - - /** - * 过滤方法 验证 token - * @param exchange 请求的上下文 通过这个参数 可以获取到 请求对象 以及 响应对象 - * @param chain 网关过滤器链 chain 放行 或者 拦截 - * @return Mono - */ - @Override - public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - // 验证当前的请求 是否需要拦截 【配置白名单请求 不拦截的请求 】 将白名单请求配置到配置文件中 - // 获取系统白名单请求 - List whites = ignoreWhiteConfig.getWhites(); - // 获取当前的请求 URI - ServerHttpRequest request = exchange.getRequest(); - String path = request.getURI().getPath(); - boolean matches = StringUtils.matches(path, whites); - if (matches) { // 放行 - return chain.filter(exchange); - } - // 获取token - String token = request.getHeaders().getFirst(TokenConstants.TOKEN); - // token 非空验证 - if (StringUtils.isEmpty(token)) { - // 不放行 提示错误信息 - return GatewayUtils.errorResponse(exchange, "token不能为空!", HttpStatus.UNAUTHORIZED); - } - try { - // token 合法性性 - JwtUtils.parseToken(token); - } catch (Exception ex) { - return GatewayUtils.errorResponse(exchange, "token格式错误!"); - } - // token 是否过期 - // 获取 UserKey - String userKey = JwtUtils.getUserKey(token); - if (!redisTemplate.hasKey(TokenConstants.LOGIN_TOKEN_KEY + userKey)) { - return GatewayUtils.errorResponse(exchange, "token过期!"); - } - // 放行 - return chain.filter(exchange); - } - - /** - * 当存在多个filter的时候 用来执行执行的优先级 - * @return 数字 数字的值越小 执行的优先级越高 - */ - @Override - public int getOrder() { - return 0; - } -} +//package com.bwie.gateway.filters; +// +//import com.bwie.common.constants.TokenConstants; +//import com.bwie.common.utils.JwtUtils; +//import com.bwie.common.utils.StringUtils; +//import com.bwie.gateway.config.IgnoreWhiteConfig; +//import com.bwie.gateway.utils.GatewayUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.cloud.gateway.filter.GatewayFilterChain; +//import org.springframework.cloud.gateway.filter.GlobalFilter; +//import org.springframework.core.Ordered; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.server.reactive.ServerHttpRequest; +//import org.springframework.stereotype.Component; +//import org.springframework.web.server.ServerWebExchange; +//import reactor.core.publisher.Mono; +// +//import java.util.List; +// +///** +// * @ClassName: +// * @Description: 鉴权过滤器 +// * @Author: zhuwenqiang +// * @Date: 2023/8/18 +// */ +//@Component +//public class AuthFilter implements GlobalFilter, Ordered { +// +// @Autowired +// private IgnoreWhiteConfig ignoreWhiteConfig; +// +// @Autowired +// private RedisTemplate redisTemplate; +// +// /** +// * 过滤方法 验证 token +// * @param exchange 请求的上下文 通过这个参数 可以获取到 请求对象 以及 响应对象 +// * @param chain 网关过滤器链 chain 放行 或者 拦截 +// * @return Mono +// */ +// @Override +// public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { +// // 验证当前的请求 是否需要拦截 【配置白名单请求 不拦截的请求 】 将白名单请求配置到配置文件中 +// // 获取系统白名单请求 +// List whites = ignoreWhiteConfig.getWhites(); +// // 获取当前的请求 URI +// ServerHttpRequest request = exchange.getRequest(); +// String path = request.getURI().getPath(); +// boolean matches = StringUtils.matches(path, whites); +// if (matches) { // 放行 +// return chain.filter(exchange); +// } +// // 获取token +// String token = request.getHeaders().getFirst(TokenConstants.TOKEN); +// // token 非空验证 +// if (StringUtils.isEmpty(token)) { +// // 不放行 提示错误信息 +// return GatewayUtils.errorResponse(exchange, "token不能为空!", HttpStatus.UNAUTHORIZED); +// } +// try { +// // token 合法性性 +// JwtUtils.parseToken(token); +// } catch (Exception ex) { +// return GatewayUtils.errorResponse(exchange, "token格式错误!"); +// } +// // token 是否过期 +// // 获取 UserKey +// String userKey = JwtUtils.getUserKey(token); +// if (!redisTemplate.hasKey(TokenConstants.LOGIN_TOKEN_KEY + userKey)) { +// return GatewayUtils.errorResponse(exchange, "token过期!"); +// } +// // 放行 +// return chain.filter(exchange); +// } +// +// /** +// * 当存在多个filter的时候 用来执行执行的优先级 +// * @return 数字 数字的值越小 执行的优先级越高 +// */ +// @Override +// public int getOrder() { +// return 0; +// } +//} diff --git a/bwie-models/bwie-sell/.gitignore b/bwie-models/bwie-sell/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/bwie-models/bwie-sell/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/bwie-models/bwie-sell/pom.xml b/bwie-models/bwie-sell/pom.xml new file mode 100644 index 0000000..cb0f70a --- /dev/null +++ b/bwie-models/bwie-sell/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + + com.bwie + bwie-models + 1.0-SNAPSHOT + + + bwie-sell + + + 8 + 8 + UTF-8 + + + + + com.bwie + bwie-common + + + + org.springframework.boot + spring-boot-starter-web + + + + com.alibaba + druid-spring-boot-starter + 1.2.8 + + + + mysql + mysql-connector-java + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.2.2 + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.4.1 + + + + org.springframework.boot + spring-boot-starter-test + test + + + com.github.tobato + fastdfs-client + 1.26.5 + + + + + + org.apache.poi + poi-ooxml + 3.17 + + + org.apache.poi + poi-ooxml-schemas + 3.17 + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + + com.alibaba + easyexcel + 2.2.7 + + + \ No newline at end of file diff --git a/bwie-models/bwie-sell/src/main/java/com/bwie/sell/SellApplication.java b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/SellApplication.java new file mode 100644 index 0000000..acbdd0b --- /dev/null +++ b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/SellApplication.java @@ -0,0 +1,16 @@ +package com.bwie.sell; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author 86175 + */ +@SpringBootApplication +public class SellApplication { + + public static void main(String[] args) { + SpringApplication.run(SellApplication.class,args); + } + +} diff --git a/bwie-models/bwie-sell/src/main/java/com/bwie/sell/controller/SellController.java b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/controller/SellController.java new file mode 100644 index 0000000..26bf7c1 --- /dev/null +++ b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/controller/SellController.java @@ -0,0 +1,73 @@ +package com.bwie.sell.controller; + +import com.alibaba.fastjson.JSON; +import com.bwie.common.pojo.Sell; +import com.bwie.common.result.Result; +import com.bwie.sell.service.SellService; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +import static org.bouncycastle.asn1.cmc.CMCStatus.success; + +/** + * @author 86175 + */ +@RestController +@RequestMapping("/sell") +@Log4j2 +public class SellController { + + @Autowired + public SellService sellService; + @Autowired + public HttpServletRequest request; + + + /** + * 商品销售统计 + * 查出每台售货机卖的 + */ + @PostMapping("/shopStatistics") + public Result> listResult (){ + + log.info("功能描述:销售日志统计,请求URI:{},请求方式:{}",request.getServletPath(),request.getMethod()); + List sell=sellService.list(); + Result> success = Result.success(sell); + log.info("功能描述:销售日志统计,请求URI:{},请求方式:{},响应结果:{}",request.getServletPath(),request.getMethod(), JSON.toJSONString(success)); + return success; + } + /** + * 销售统计表展示 + */ + @PostMapping("/salesStatistics") + public Result> salesStatistics (){ + + log.info("功能描述:销售金额统计,请求URI:{},请求方式:{}",request.getServletPath(),request.getMethod()); + List sell=sellService.sellList(); + Result> success = Result.success(sell); + log.info("功能描述:销售金额统计,请求URI:{},请求方式:{},响应结果:{}",request.getServletPath(),request.getMethod(), JSON.toJSONString(success)); + return success; + } + + /** + * 商品销售统计导出 + */ + @PostMapping("/exportSell") + public Result exportSell(HttpServletResponse response){ +// Result success = + //先查询数据 + System.out.println(response); + log.info("功能描述:销售导出查询,请求URI:{},请求方式:{},请求参数{}",request.getServletPath(),request.getMethod(),response); + Result success =sellService.exportSell(response); + log.info("功能描述:销售导出查询,请求URI:{},请求方式:{},响应结果:{}",request.getServletPath(),request.getMethod(), JSON.toJSONString(success)); + return success; + + } +} diff --git a/bwie-models/bwie-sell/src/main/java/com/bwie/sell/mapper/SellMapper.java b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/mapper/SellMapper.java new file mode 100644 index 0000000..c386a71 --- /dev/null +++ b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/mapper/SellMapper.java @@ -0,0 +1,28 @@ +package com.bwie.sell.mapper; + +import com.bwie.common.pojo.Sell; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * @author 86175 + */ +@Mapper +public interface SellMapper { + + /** + * 商品销售统计 + * @return + */ + List shopList(); + + /** + * 商品售价统计 + * @return + */ + List sellList(); + + + +} diff --git a/bwie-models/bwie-sell/src/main/java/com/bwie/sell/service/SellService.java b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/service/SellService.java new file mode 100644 index 0000000..94dc785 --- /dev/null +++ b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/service/SellService.java @@ -0,0 +1,29 @@ +package com.bwie.sell.service; + +import com.bwie.common.pojo.Sell; +import com.bwie.common.result.Result; +import com.github.pagehelper.PageInfo; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author 86175 + */ +public interface SellService { + + List list(); + + + List sellList(); + + + Result exportSell(HttpServletResponse response); + + + List findStudentListAll(); + + + PageInfo findStudentList(int i, Integer sheetSize); + +} diff --git a/bwie-models/bwie-sell/src/main/java/com/bwie/sell/service/impl/SellServiceImpl.java b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/service/impl/SellServiceImpl.java new file mode 100644 index 0000000..909f822 --- /dev/null +++ b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/service/impl/SellServiceImpl.java @@ -0,0 +1,68 @@ +package com.bwie.sell.service.impl; + +import com.bwie.common.pojo.Sell; +import com.bwie.common.result.Result; +import com.bwie.common.utils.poi.ExcelUtil; +import com.bwie.sell.mapper.SellMapper; +import com.bwie.sell.service.SellService; +import com.bwie.sell.util.poi3.EasyExcelUtil; +import com.github.pagehelper.PageInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author 86175 + */ +@Service +public class SellServiceImpl implements SellService { + + @Autowired + public SellMapper sellMapper; + + @Autowired + public EasyExcelUtil easyExcelUtil; + + + @Override + public List list() { + return sellMapper.shopList(); + } + + @Override + public List sellList() { + return sellMapper.sellList(); + } + + @Override + public Result exportSell(HttpServletResponse response) { + + List sells = sellMapper.sellList(); + //是以流的方式把数据传给用户 + ExcelUtil sellExcelUtil = new ExcelUtil<>(Sell.class); + /** + * sellExcelUtil 对象中的导出的方法 中第一次参数的是: + * 响应对象 + * 第二个参数是: + * 查询到的list集合 + * 第三个参数是: + * sheet名称 + * + */ + String s = sellExcelUtil.exportExcel(sells, "商品销售统计"); +// return Result.success(); + return Result.success(s); + } + + @Override + public List findStudentListAll() { + return null; + } + + @Override + public PageInfo findStudentList(int i, Integer sheetSize) { + return null; + } +} diff --git a/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/FastUtil.java b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/FastUtil.java new file mode 100644 index 0000000..7660d2b --- /dev/null +++ b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/FastUtil.java @@ -0,0 +1,55 @@ +package com.bwie.sell.util; + +import org.springframework.stereotype.Component; +import com.github.tobato.fastdfs.domain.fdfs.StorePath; +import com.github.tobato.fastdfs.service.FastFileStorageClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; + +/** + * @BelongsProject: 0107day02 + * @BelongsPackage: com.bw.config + * @Author: zhupengfei + * @CreateTime: 2023-02-01 08:52 + */ +@Component +public class FastUtil { + private static final Logger log = LoggerFactory.getLogger(FastUtil.class); + + @Resource + private FastFileStorageClient storageClient ; + + /** + * 上传文件 + */ + public String upload(MultipartFile multipartFile) throws Exception{ + String originalFilename = multipartFile.getOriginalFilename(). + substring(multipartFile.getOriginalFilename(). + lastIndexOf(".") + 1); + StorePath storePath = this.storageClient.uploadImageAndCrtThumbImage( + multipartFile.getInputStream(), + multipartFile.getSize(),originalFilename , null); + return storePath.getFullPath() ; + } + /** + * 删除文件 + */ + public String deleteFile(String fileUrl) { + if (StringUtils.isEmpty(fileUrl)) { + log.info("fileUrl == >>文件路径为空..."); + return "文件路径不能为空"; + } + try { + StorePath storePath = StorePath.parseFromUrl(fileUrl); + storageClient.deleteFile(storePath.getGroup(), storePath.getPath()); + } catch (Exception e) { + log.error(e.getMessage()); + } + return "删除成功"; + } + +} diff --git a/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/poi3/CustomCellStyle.java b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/poi3/CustomCellStyle.java new file mode 100644 index 0000000..5ed74d9 --- /dev/null +++ b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/poi3/CustomCellStyle.java @@ -0,0 +1,76 @@ +package com.bwie.sell.util.poi3; + +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.*; + +import java.util.List; + +public class CustomCellStyle implements CellWriteHandler { + + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + + + } + + @Override + public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + //获取工作簿 + Workbook workbook = writeSheetHolder.getSheet().getWorkbook(); + + //获取单元格样式 + CellStyle cellStyle = workbook.createCellStyle(); + + //判断非首行 + if(!isHead && cell.getColumnIndex()==2){ + + String stringCellValue = cell.getStringCellValue(); + + //double numericCellValue = cell.getNumericCellValue(); + if("女".equals(stringCellValue)){ + //填充背景色 + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + cellStyle.setFillForegroundColor(IndexedColors.RED.index); + + //设置字体 + Font font = workbook.createFont(); + font.setBold(true); + font.setColor(IndexedColors.BLACK.getIndex()); + cellStyle.setFont(font); + } + + + }else{} + + //设置边框 + cellStyle.setBorderTop(BorderStyle.THIN); + cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); + + cellStyle.setBorderRight(BorderStyle.THIN); + cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); + + cellStyle.setBorderBottom(BorderStyle.THIN); + cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); + + cellStyle.setBorderLeft(BorderStyle.THIN); + cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); + + cell.setCellStyle(cellStyle); + + } +} diff --git a/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/poi3/EasyExcelUtil.java b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/poi3/EasyExcelUtil.java new file mode 100644 index 0000000..4a122ed --- /dev/null +++ b/bwie-models/bwie-sell/src/main/java/com/bwie/sell/util/poi3/EasyExcelUtil.java @@ -0,0 +1,193 @@ +package com.bwie.sell.util.poi3; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.util.CollectionUtils; +import com.alibaba.excel.write.merge.AbstractMergeStrategy; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.bwie.common.pojo.Sell; +import com.bwie.sell.service.SellService; +import com.github.pagehelper.PageInfo; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.security.sasl.SaslServer; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +// 自定义合并策略 该类继承了AbstractMergeStrategy抽象合并策略,需要重写merge()方法 +@Component +@Data +@NoArgsConstructor +public class EasyExcelUtil extends AbstractMergeStrategy { + + + @Autowired + private SellService sellService; + + /** + * 分组,每几行合并一次 + */ + private List exportFieldGroupCountList; + + /** + * 目标合并列index + */ + private Integer targetColumnIndex; + + // 需要开始合并单元格的首行index + private Integer rowIndex; + + // exportDataList为待合并目标列的值 + public EasyExcelUtil(List exportDataList, Integer targetColumnIndex) { + this.exportFieldGroupCountList = getGroupCountList(exportDataList); + this.targetColumnIndex = targetColumnIndex; + } + + + @Override + protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { + + if (null == rowIndex) { + rowIndex = cell.getRowIndex(); + } + // 仅从首行以及目标列的单元格开始合并,忽略其他 + if (cell.getRowIndex() == rowIndex && cell.getColumnIndex() == targetColumnIndex) { + mergeGroupColumn(sheet); + } + } + + private void mergeGroupColumn(Sheet sheet) { + int rowCount = rowIndex; + for (Integer count : exportFieldGroupCountList) { + if(count == 1) { + rowCount += count; + continue ; + } + // 合并单元格 + CellRangeAddress cellRangeAddress = new CellRangeAddress(rowCount, rowCount + count - 1, targetColumnIndex, targetColumnIndex); + sheet.addMergedRegionUnsafe(cellRangeAddress); + rowCount += count; + } + } + + // 该方法将目标列根据值是否相同连续可合并,存储可合并的行数 + private List getGroupCountList(List exportDataList){ + if (CollectionUtils.isEmpty(exportDataList)) { + return new ArrayList<>(); + } + + List groupCountList = new ArrayList<>(); + int count = 1; + + for (int i = 1; i < exportDataList.size(); i++) { + if (exportDataList.get(i).equals(exportDataList.get(i - 1))) { + count++; + } else { + groupCountList.add(count); + count = 1; + } + } + // 处理完最后一条后 + groupCountList.add(count); + return groupCountList; + } + + + // 修改WriteSheet的代码如下 + public void writeExcel(HttpServletResponse response,String fileName,Integer mergeIndex,String firstTitle,String [] secondTile,Integer sheetSize) { + // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + try { + String name = URLEncoder.encode(fileName, "UTF-8"); + + response.setHeader("Content-disposition", "attachment;filename=" + name + ".xlsx"); + + List> heads = new ArrayList<>(); + for (int i = 0; i < secondTile.length; i++) { + heads.add(Arrays.asList(firstTitle,secondTile[i])); + } + + + ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()) + .build(); + + List studentListAll = sellService.findStudentListAll(); + //select * from t_student limit 0,2 1 (pageNum-1)*pageSize + //select * from t_student limit 2,2 2 + //select * from t_student limit 4,2 3 + //select * from t_student limit 6,2 4 + + Integer count = studentListAll.size(); + Integer sheets = (int)Math.ceil((double)count/sheetSize); + + for (int i = 0; i < sheets; i++) { + PageInfo studentList = sellService.findStudentList(i + 1, sheetSize); + WriteSheet sheet1 = EasyExcel.writerSheet(i, "模版"+(i+1)).head(Sell.class) + .head(heads).registerWriteHandler(new EasyExcelUtil(studentList.getList().stream().map(Sell::getPhone).collect(Collectors.toList()), mergeIndex)) + .registerWriteHandler(new CustomCellStyle()).build(); + + + excelWriter.write(studentList.getList(),sheet1); + } + excelWriter.finish(); + response.flushBuffer(); + + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + + // 修改WriteSheet的代码如下 + public void writeExcel(HttpServletResponse response,String fileName, List list,String [] secondTile) { + // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + try { + String name = URLEncoder.encode(fileName, "UTF-8"); + + response.setHeader("Content-disposition", "attachment;filename=" + name + ".xlsx"); + + List> heads = new ArrayList<>(); + for (int i = 0; i < secondTile.length; i++) { + heads.add(Arrays.asList(secondTile[i])); + } + + + EasyExcel.write(response.getOutputStream(),Sell.class).sheet("模板").head(Sell.class) + .head(heads) + //.registerWriteHandler(new EasyExcelUtil(list.stream().map(Student::getName).collect(Collectors.toList()), mergeIndex)) + //.registerWriteHandler(new CustomCellStyle()) //设置单元格颜色样式 + .doWrite(list); + + + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + + +} \ No newline at end of file diff --git a/bwie-models/bwie-sell/src/main/resources/bootstrap.yml b/bwie-models/bwie-sell/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..45b0ad8 --- /dev/null +++ b/bwie-models/bwie-sell/src/main/resources/bootstrap.yml @@ -0,0 +1,58 @@ +# Tomcat +server: + port: 9004 +# Spring +spring: + rabbitmq: + host: 111.229.234.119 + port: 5672 + userName: guest + password: guest + listener: + simple: + prefetch: 1 + publisher-confirm-type: correlated + publisher-returns: true + main: + allow-circular-references: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + application: + # 应用名称 + name: bwie-sell + profiles: + # 环境配置 + active: dev + cloud: + sentinel: + transport: + # 控制台地址 + #sentinel 地址不需要改动 + dashboard: 127.0.0.1:8080 + # 指定sentinel控制台获取应用数据的端口,被占用会端口号默认 +1 + port: 8719 + nacos: + discovery: + # 服务注册地址 + server-addr: 111.229.234.119:8848 + config: + # 配置中心地址 + server-addr: 111.229.234.119:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +fdfs: + so-timeout: 1500 # socket 连接时长 + connect-timeout: 600 # 连接 tracker 服务器超时时长 + # 这两个是你服务器的 IP 地址,注意 23000 端口也要打开,阿里云服务器记得配置安全组。tracker 要和 stroage 服务进行交流 + tracker-list: 111.229.234.119:22122 + web-server-url: 111.229.234.119:8888 + pool: + jmx-enabled: false + # 生成缩略图 + thumb-image: + height: 500 + width: 500 diff --git a/bwie-models/bwie-sell/src/main/resources/mapper/SellMapper.xml b/bwie-models/bwie-sell/src/main/resources/mapper/SellMapper.xml new file mode 100644 index 0000000..bab949b --- /dev/null +++ b/bwie-models/bwie-sell/src/main/resources/mapper/SellMapper.xml @@ -0,0 +1,59 @@ + + + + + + + diff --git a/bwie-models/bwie-user/src/main/resources/bootstrap.yml b/bwie-models/bwie-user/src/main/resources/bootstrap.yml index 3099172..f75fc4c 100644 --- a/bwie-models/bwie-user/src/main/resources/bootstrap.yml +++ b/bwie-models/bwie-user/src/main/resources/bootstrap.yml @@ -1,6 +1,6 @@ # Tomcat server: - port: 9004 + port: 9002 # Spring spring: rabbitmq: diff --git a/bwie-models/pom.xml b/bwie-models/pom.xml index 69c26c3..2a92926 100644 --- a/bwie-models/pom.xml +++ b/bwie-models/pom.xml @@ -13,6 +13,7 @@ pom bwie-user + bwie-sell diff --git a/f95ab62a-c2f3-4314-a2e6-ea20f916ad3c_商品销售统计.xlsx b/f95ab62a-c2f3-4314-a2e6-ea20f916ad3c_商品销售统计.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a58c6589b0885c8ff1a6edfbab5540123de905f5 GIT binary patch literal 4282 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 C?FqgB literal 0 HcmV?d00001