diff --git a/docker/copy.sh b/docker/copy.sh
index b967d51b..ec2915b8 100644
--- a/docker/copy.sh
+++ b/docker/copy.sh
@@ -9,8 +9,8 @@ usage() {
# copy sql
echo "begin copy sql "
-cp ../sql/ry_20210908.sql ./mysql/db
-cp ../sql/ry_config_20220114.sql ./mysql/db
+cp ../sql/ry_20220814.sql ./mysql/db
+cp ../sql/ry_config_20220510.sql ./mysql/db
# copy html
echo "begin copy html "
diff --git a/docker/nacos/conf/application.properties b/docker/nacos/conf/application.properties
index e0034a9c..7f2a61f2 100644
--- a/docker/nacos/conf/application.properties
+++ b/docker/nacos/conf/application.properties
@@ -16,7 +16,7 @@ management.metrics.export.influx.enabled=false
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
-server.tomcat.basedir=
+server.tomcat.basedir=/home/ruoyi/nacos/tomcat/logs
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
diff --git a/pom.xml b/pom.xml
index 822fe8d2..35eba21d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,12 +17,12 @@
UTF-8
UTF-8
1.8
- 2.7.1
+ 2.7.2
2021.0.3
2021.0.1.0
2.0.4
1.5.1
- 2.7.2
+ 2.7.3
2.2.2
3.0.0
1.6.2
@@ -34,7 +34,7 @@
2.11.0
1.4
2.3
- 2.0.9
+ 2.0.12
0.9.1
8.2.2
4.1.2
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictData.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictData.java
index dadca63b..014a6915 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictData.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictData.java
@@ -131,7 +131,7 @@ public class SysDictData extends BaseEntity
public boolean getDefault()
{
- return UserConstants.YES.equals(this.isDefault) ? true : false;
+ return UserConstants.YES.equals(this.isDefault);
}
public String getIsDefault()
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysRole.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysRole.java
index 8305b993..04a4d0ef 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysRole.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysRole.java
@@ -1,5 +1,6 @@
package com.ruoyi.system.api.domain;
+import java.util.Set;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -59,6 +60,9 @@ public class SysRole extends BaseEntity
/** 部门组(数据权限) */
private Long[] deptIds;
+ /** 角色菜单权限 */
+ private Set permissions;
+
public SysRole()
{
@@ -204,6 +208,16 @@ public class SysRole extends BaseEntity
this.deptIds = deptIds;
}
+ public Set getPermissions()
+ {
+ return permissions;
+ }
+
+ public void setPermissions(Set permissions)
+ {
+ this.permissions = permissions;
+ }
+
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
index 37d5e46a..7f674b60 100644
--- a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
+++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
@@ -59,16 +59,17 @@ public class SysLoginService
// 查询用户信息
R userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
- if (R.FAIL == userResult.getCode())
- {
- throw new ServiceException(userResult.getMsg());
- }
-
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
throw new ServiceException("登录用户:" + username + " 不存在");
}
+
+ if (R.FAIL == userResult.getCode())
+ {
+ throw new ServiceException(userResult.getMsg());
+ }
+
LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser();
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysPasswordService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysPasswordService.java
index 06e111a7..eb18ea87 100644
--- a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysPasswordService.java
+++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysPasswordService.java
@@ -21,9 +21,9 @@ public class SysPasswordService
@Autowired
private RedisService redisService;
- private int maxRetryCount = CacheConstants.passwordMaxRetryCount;
+ private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT;
- private Long lockTime = CacheConstants.passwordLockTime;
+ private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME;
@Autowired
private SysRecordLogService recordLogService;
@@ -60,7 +60,7 @@ public class SysPasswordService
if (!matches(user, password))
{
retryCount = retryCount + 1;
- recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, String.format("密码输入错误%s次", maxRetryCount));
+ recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, String.format("密码输入错误%s次", retryCount));
redisService.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
throw new ServiceException("用户不存在/密码错误");
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excel.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excel.java
index fd20df19..10f9a91b 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excel.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excel.java
@@ -83,6 +83,11 @@ public @interface Excel
*/
public String[] combo() default {};
+ /**
+ * 是否需要纵向合并单元格,应对需求:含有list集合单元格)
+ */
+ public boolean needMerge() default false;
+
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java
index e63d95ec..38e556b0 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java
@@ -20,12 +20,12 @@ public class CacheConstants
/**
* 密码最大错误次数
*/
- public final static int passwordMaxRetryCount = 5;
+ public final static int PASSWORD_MAX_RETRY_COUNT = 5;
/**
* 密码锁定时间,默认10(分钟)
*/
- public final static long passwordLockTime = 10;
+ public final static long PASSWORD_LOCK_TIME = 10;
/**
* 权限缓存前缀
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
index 69031a35..c7e1f34e 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -17,6 +17,11 @@ public class Constants
*/
public static final String GBK = "GBK";
+ /**
+ * www主域
+ */
+ public static final String WWW = "www.";
+
/**
* RMI 远程方法调用
*/
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java
index aecbd95a..d02baeb0 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java
@@ -41,4 +41,9 @@ public class SecurityConstants
* 登录用户
*/
public static final String LOGIN_USER = "login_user";
+
+ /**
+ * 角色权限
+ */
+ public static final String ROLE_PERMISSION = "role_permission";
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SecurityContextHolder.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SecurityContextHolder.java
index 0a66f38f..2a8dde84 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SecurityContextHolder.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SecurityContextHolder.java
@@ -81,6 +81,16 @@ public class SecurityContextHolder
set(SecurityConstants.USER_KEY, userKey);
}
+ public static String getPermission()
+ {
+ return get(SecurityConstants.ROLE_PERMISSION);
+ }
+
+ public static void setPermission(String permissions)
+ {
+ set(SecurityConstants.ROLE_PERMISSION, permissions);
+ }
+
public static void remove()
{
THREAD_LOCAL.remove();
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java
index 562a3482..f1878deb 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java
@@ -294,6 +294,32 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
}
+ /**
+ * 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
+ *
+ * @param set 给定的集合
+ * @param array 给定的数组
+ * @return boolean 结果
+ */
+ public static boolean containsAny(Collection collection, String... array)
+ {
+ if (isEmpty(collection) || isEmpty(array))
+ {
+ return false;
+ }
+ else
+ {
+ for (String str : array)
+ {
+ if (collection.contains(str))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
/**
* 驼峰转下划线命名
*/
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/HTMLFilter.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/HTMLFilter.java
index 1052b55a..ba53dc93 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/HTMLFilter.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/HTMLFilter.java
@@ -332,7 +332,7 @@ public final class HTMLFilter
final String name = m.group(1).toLowerCase();
if (allowed(name))
{
- if (false == inArray(name, vSelfClosingTags))
+ if (!inArray(name, vSelfClosingTags))
{
if (vTagCounts.containsKey(name))
{
@@ -387,7 +387,7 @@ public final class HTMLFilter
{
paramValue = processParamProtocol(paramValue);
}
- params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\"");
+ params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\"");
}
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java
index c813f85b..f170010e 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java
@@ -4,12 +4,14 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
@@ -20,6 +22,7 @@ import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RegExUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
@@ -126,6 +129,26 @@ public class ExcelUtil
*/
private short maxHeight;
+ /**
+ * 合并后最后行数
+ */
+ private int subMergedLastRowNum = 0;
+
+ /**
+ * 合并后开始行数
+ */
+ private int subMergedFirstRowNum = 1;
+
+ /**
+ * 对象的子列表方法
+ */
+ private Method subMethod;
+
+ /**
+ * 对象的子列表属性
+ */
+ private List subFields;
+
/**
* 统计列表
*/
@@ -175,6 +198,7 @@ public class ExcelUtil
createExcelField();
createWorkbook();
createTitle();
+ createSubHead();
}
/**
@@ -184,19 +208,54 @@ public class ExcelUtil
{
if (StringUtils.isNotEmpty(title))
{
+ subMergedFirstRowNum++;
+ subMergedLastRowNum++;
+ int titleLastCol = this.fields.size() - 1;
+ if (isSubList())
+ {
+ titleLastCol = titleLastCol + subFields.size() - 1;
+ }
Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
titleRow.setHeightInPoints(30);
Cell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(styles.get("title"));
titleCell.setCellValue(title);
- sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(),
- this.fields.size() - 1));
+ sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol));
+ }
+ }
+
+ /**
+ * 创建对象的子列表名称
+ */
+ public void createSubHead()
+ {
+ if (isSubList())
+ {
+ subMergedFirstRowNum++;
+ subMergedLastRowNum++;
+ Row subRow = sheet.createRow(rownum);
+ int excelNum = 0;
+ for (Object[] objects : fields)
+ {
+ Excel attr = (Excel) objects[1];
+ Cell headCell1 = subRow.createCell(excelNum);
+ headCell1.setCellValue(attr.name());
+ headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
+ excelNum++;
+ }
+ int headFirstRow = excelNum - 1;
+ int headLastRow = headFirstRow + subFields.size() - 1;
+ if (headLastRow > headFirstRow)
+ {
+ sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow));
+ }
+ rownum++;
}
}
/**
* 对excel表单默认第一个索引名转换成list
- *
+ *
* @param is 输入流
* @return 转换后集合
*/
@@ -207,7 +266,7 @@ public class ExcelUtil
/**
* 对excel表单默认第一个索引名转换成list
- *
+ *
* @param is 输入流
* @param titleNum 标题占用行数
* @return 转换后集合
@@ -219,7 +278,7 @@ public class ExcelUtil
/**
* 对excel表单指定表格索引名转换成list
- *
+ *
* @param sheetName 表格索引名
* @param titleNum 标题占用行数
* @param is 输入流
@@ -378,7 +437,6 @@ public class ExcelUtil
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @return 结果
- * @throws IOException
*/
public void exportExcel(HttpServletResponse response, List list, String sheetName)
{
@@ -393,7 +451,6 @@ public class ExcelUtil
* @param sheetName 工作表的名称
* @param title 标题
* @return 结果
- * @throws IOException
*/
public void exportExcel(HttpServletResponse response, List list, String sheetName, String title)
{
@@ -431,7 +488,7 @@ public class ExcelUtil
/**
* 对list数据源将其里面的数据导入到excel表单
- *
+ *
* @return 结果
*/
public void exportExcel(HttpServletResponse response)
@@ -468,8 +525,20 @@ public class ExcelUtil
// 写入各个字段的列头名称
for (Object[] os : fields)
{
+ Field field = (Field) os[0];
Excel excel = (Excel) os[1];
- this.createCell(excel, row, column++);
+ if (Collection.class.isAssignableFrom(field.getType()))
+ {
+ for (Field subField : subFields)
+ {
+ Excel subExcel = subField.getAnnotation(Excel.class);
+ this.createHeadCell(subExcel, row, column++);
+ }
+ }
+ else
+ {
+ this.createHeadCell(excel, row, column++);
+ }
}
if (Type.EXPORT.equals(type))
{
@@ -481,32 +550,71 @@ public class ExcelUtil
/**
* 填充excel数据
- *
+ *
* @param index 序号
* @param row 单元格行
*/
+ @SuppressWarnings("unchecked")
public void fillExcelData(int index, Row row)
{
int startNo = index * sheetSize;
int endNo = Math.min(startNo + sheetSize, list.size());
+ int rowNo = (1 + rownum) - startNo;
for (int i = startNo; i < endNo; i++)
{
- row = sheet.createRow(i + 1 + rownum - startNo);
+ rowNo = i > 1 ? rowNo + 1 : rowNo + i;
+ row = sheet.createRow(rowNo);
// 得到导出对象.
T vo = (T) list.get(i);
+ Collection> subList = null;
+ if (isSubListValue(vo))
+ {
+ subList = getListCellValue(vo);
+ subMergedLastRowNum = subMergedLastRowNum + subList.size();
+ }
+
int column = 0;
for (Object[] os : fields)
{
Field field = (Field) os[0];
Excel excel = (Excel) os[1];
- this.addCell(excel, row, vo, field, column++);
+ if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList))
+ {
+ boolean subFirst = false;
+ for (Object obj : subList)
+ {
+ if (subFirst)
+ {
+ rowNo++;
+ row = sheet.createRow(rowNo);
+ }
+ List subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class);
+ int subIndex = 0;
+ for (Field subField : subFields)
+ {
+ if (subField.isAnnotationPresent(Excel.class))
+ {
+ subField.setAccessible(true);
+ Excel attr = subField.getAnnotation(Excel.class);
+ this.addCell(attr, row, (T) obj, subField, column + subIndex);
+ }
+ subIndex++;
+ }
+ subFirst = true;
+ }
+ this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size();
+ }
+ else
+ {
+ this.addCell(excel, row, vo, field, column++);
+ }
}
}
}
/**
* 创建表格样式
- *
+ *
* @param wb 工作薄对象
* @return 样式列表
*/
@@ -634,7 +742,7 @@ public class ExcelUtil
/**
* 创建单元格
*/
- public Cell createCell(Excel attr, Row row, int column)
+ public Cell createHeadCell(Excel attr, Row row, int column)
{
// 创建列
Cell cell = row.createCell(column);
@@ -642,12 +750,21 @@ public class ExcelUtil
cell.setCellValue(attr.name());
setDataValidation(attr, row, column);
cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
+ if (isSubList())
+ {
+ // 填充默认样式,防止合并单元格样式失效
+ sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor())));
+ if (attr.needMerge())
+ {
+ sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column));
+ }
+ }
return cell;
}
/**
* 设置单元格信息
- *
+ *
* @param value 单元格值
* @param attr 注解相关
* @param cell 单元格信息
@@ -749,6 +866,11 @@ public class ExcelUtil
{
// 创建cell
cell = row.createCell(column);
+ if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge())
+ {
+ CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column);
+ sheet.addMergedRegion(cellAddress);
+ }
cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor())));
// 用于读取对象中的属性
@@ -766,7 +888,7 @@ public class ExcelUtil
}
else if (value instanceof BigDecimal && -1 != attr.scale())
{
- cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).toString());
+ cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue());
}
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
{
@@ -839,7 +961,7 @@ public class ExcelUtil
for (String item : convertSource)
{
String[] itemArray = item.split("=");
- if (StringUtils.containsAny(separator, propertyValue))
+ if (StringUtils.containsAny(propertyValue, separator))
{
for (String value : propertyValue.split(separator))
{
@@ -863,7 +985,7 @@ public class ExcelUtil
/**
* 反向解析值 男=0,女=1,未知=2
- *
+ *
* @param propertyValue 参数值
* @param converterExp 翻译注解
* @param separator 分隔符
@@ -876,7 +998,7 @@ public class ExcelUtil
for (String item : convertSource)
{
String[] itemArray = item.split("=");
- if (StringUtils.containsAny(separator, propertyValue))
+ if (StringUtils.containsAny(propertyValue, separator))
{
for (String value : propertyValue.split(separator))
{
@@ -1049,6 +1171,13 @@ public class ExcelUtil
field.setAccessible(true);
fields.add(new Object[] { field, attr });
}
+ if (Collection.class.isAssignableFrom(field.getType()))
+ {
+ subMethod = getSubMethod(field.getName(), clazz);
+ ParameterizedType pt = (ParameterizedType) field.getGenericType();
+ Class> subClass = (Class>) pt.getActualTypeArguments()[0];
+ this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
+ }
}
// 多注解
@@ -1097,7 +1226,7 @@ public class ExcelUtil
/**
* 创建工作表
- *
+ *
* @param sheetNo sheet数量
* @param index 序号
*/
@@ -1114,7 +1243,7 @@ public class ExcelUtil
/**
* 获取单元格值
- *
+ *
* @param row 获取的行
* @param column 获取单元格列号
* @return 单元格值
@@ -1174,7 +1303,7 @@ public class ExcelUtil
/**
* 判断是否是空行
- *
+ *
* @param row 判断的行
* @return
*/
@@ -1227,4 +1356,61 @@ public class ExcelUtil
}
return str;
}
+
+ /**
+ * 是否有对象的子列表
+ */
+ public boolean isSubList()
+ {
+ return StringUtils.isNotNull(subFields) && subFields.size() > 0;
+ }
+
+ /**
+ * 是否有对象的子列表,集合不为空
+ */
+ public boolean isSubListValue(T vo)
+ {
+ return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0;
+ }
+
+ /**
+ * 获取集合的值
+ */
+ public Collection> getListCellValue(Object obj)
+ {
+ Object value;
+ try
+ {
+ value = subMethod.invoke(obj, new Object[] {});
+ }
+ catch (Exception e)
+ {
+ return new ArrayList