使用场景:
这个场景是在Excel一对多,多对多模板导出场景下遇到的,常见的场景有财务报表,绩效报表等,存在嵌套循环的情况下,我们就需要获取对象的最大深度,以此实现循环插入,下面的行往下移动数据的最大宽度,直接贴代码
1.新建DO对象
2.标记为自定义java对象
我这里使用了ExcelDTO注解做标记,也可自定义实现接口的方式做标记
3.获取集合最大深度
4.测试
public class PerformanceService {
/**
* 标记是否是导出对象
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ExcelDTO {
}
@ExcelDTO
public static class User implements Serializable {
public User() {
}
public User(Integer age, String username) {
this.age = age;
this.username = username;
}
public User(List<User> userList, Integer age, String username) {
this.userList = userList;
this.age = age;
this.username = username;
}
public User(User user, List<User> userList, Integer age, String username) {
this.user = user;
this.userList = userList;
this.age = age;
this.username = username;
}
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
private List<User> userList = Lists.newArrayList();
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
private Integer age;
private String username;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
private static Integer getObjectMaxSize(Collection<?> datas) throws Exception {
Integer maxSize = 0;
for (Iterator iterator = datas.iterator(); iterator.hasNext(); ) {
Object object = iterator.next();
maxSize += getMaxSize(object.getClass().getDeclaredFields(), object,new AtomicInteger(0));
}
return maxSize;
}
private static boolean isJavaClass(Class<?> clz) {
Annotation[] annotations = clz.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().getSimpleName().equals("ExcelDTO")) return true;
}
return false;
}
private static String getMethodName(String fildeName) throws Exception {
byte[] items = fildeName.getBytes();
items[0] = (byte) ((char) items[0] - 'a' + 'A');
return new String(items);
}
private static Integer getMaxSize(Field[] declaredFields, Object obj, AtomicInteger loopNum) throws Exception {
Integer tempNum = 1;
int current=loopNum.get();
if(!loopNum.compareAndSet(current,current+1)||current>10){
throw new RuntimeException("对象子集引用超过深度");
}
for (Field field : declaredFields) {
if (!field.isAccessible()) field.setAccessible(true);
if (field.getType() == List.class && isJavaClass((Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0])) {//list类型
List listObject;
Method getListMethod = obj.getClass().getDeclaredMethod("get" + getMethodName(field.getName()));
listObject = (List) getListMethod.invoke(obj);
if (null == listObject || listObject.isEmpty()) {
continue;
}
Integer size = listObject.size();
tempNum = size;
for (int i = 0; i < size; i++) {
Object listDeclaredObj = listObject.get(i);
if (null == listDeclaredObj) {
continue;
}
tempNum -= 1;
tempNum += getMaxSize(listDeclaredObj.getClass().getDeclaredFields(), listDeclaredObj,loopNum);
}
} else if (isJavaClass(field.getType())) {//普通java类型
Object javaObj;
Method getListMethod = obj.getClass().getMethod("get" + getMethodName(field.getName()));
javaObj = getListMethod.invoke(obj);
if (null == javaObj) {
continue;
}
tempNum-=1;
tempNum += getMaxSize(field.getType().getDeclaredFields(), javaObj,loopNum);
continue;
}
}
return tempNum;
}
}
public static void main(String[] args) throws Exception {
ArrayList<User> obj = Lists.newArrayList();
User one = new User(1, "礼拜");
User two=new User(2,"ABC");
User three=new User(2,"dgf");
User fourths=new User(2,"hec");
User fourths2=new User(2,"hec");
User fourths3=new User(2,"hec");
User fourths4=new User(2,"hec");
// one.getUserList().add(two);
// one.getUserList().add(two);
one.setUser(three);
three.getUserList().add(fourths);
three.getUserList().add(fourths2);
three.getUserList().add(fourths3);
three.getUserList().add(fourths4);
obj.add(one);
System.out.println(getObjectMaxSize(obj));
// System.out.println(new AtomicInteger(1).compareAndSet(1, 2));
}
网友评论