com.gitee.beiding.template_excel.ValueHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of template-excel Show documentation
Show all versions of template-excel Show documentation
使用模板快速提取excel文件中的数据为数据实体,或者使用模板将数据实体渲染成excel
package com.gitee.beiding.template_excel;
import java.lang.reflect.*;
import java.util.*;
/*
根据变量名称构建H对象,H对象维护数据的上下级关系
例如
a.list[i].d
H(a)->H(list[i])->H(d)
H对象在处理的过程中,会先给叶子节点赋值,然后从叶子
*/
class ValueHandler {
private Map> entityMapping;
//属性的setter方法
private Map setterMap = new HashMap<>();
void setEntityMapping(Map> entityMapping) {
this.entityMapping = new HashMap<>();
Set names = new HashSet<>();
//首先将当前元素放入
entityMapping.forEach((k, c) -> {
String name = k.replaceAll("(?<=\\[)[^\\[\\]]*(?=])", "").replaceAll("[\n \t]*", "");
this.entityMapping.put(name, c);
names.add(name);
});
for (String name : names) {
putAndHandleFiledType(name, this.entityMapping.get(name));
}
}
//分析setter方法
private void putAndHandleFiledType(String name, Class> type) {
Class> c = this.entityMapping.get(name);
//如果类型已经存在就使用已经存在的类型作为解析依据
if (c == null) {
this.entityMapping.put(name, type);
} else {
type = c;
}
Map map = settterMethodMap(type);
//解析类中的所有变量
for (Field field : fields(type)) {
String fn = field.getName();
//计算setter方法
String setterMethodName = setterName(fn);
try {
Method method = map.get(setterMethodName);
if (method != null) {
//如果是列表只能是List
if (field.getType() == List.class) {
Type genericType = field.getGenericType();
//判断是否是具有参数的
if (genericType instanceof ParameterizedType) {
Type[] types = ((ParameterizedType) genericType).getActualTypeArguments();
if (types.length == 1) {
Type t = types[0];
String typeName = t.getTypeName();
Class> aClass = Class.forName(typeName);
String subN = name + "." + fn + "[]";
//放入setter方法
setterMap.put(subN, method);
putAndHandleFiledType(subN, aClass);
}
}
} else {
String subN = name + "." + fn;
setterMap.put(subN, method);
putAndHandleFiledType(subN, field.getType());
}
}
} catch (Exception ignore) {
}
}
}
private static Map settterMethodMap(Class> clazz) {
Map map = new HashMap<>();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.getName().startsWith("set")) {
map.put(method.getName(), method);
}
}
return map;
}
private static String setterName(String s) {
String setterMethodName = "set" + s.substring(0, 1).toUpperCase();
if (s.length() > 1) {
setterMethodName += s.substring(1);
}
return setterMethodName;
}
private static List fields(Class> cls) {
List list = new ArrayList<>();
while (cls != null && cls != Object.class) {
Field[] fields = cls.getDeclaredFields();
list.addAll(Arrays.asList(fields));
cls = cls.getSuperclass();
}
return list;
}
private static interface ValueHanle {
Object hanle(String t);
}
public static Map hanleMap = new HashMap<>();
static {
hanleMap.put(Integer.class, text -> (Integer) Double.valueOf(text).intValue());
hanleMap.put(int.class, text -> (Integer) Double.valueOf(text).intValue());
hanleMap.put(Character.class, text -> (Character) Character.highSurrogate(Double.valueOf(text).intValue()));
hanleMap.put(char.class, text -> (Character) Character.highSurrogate(Double.valueOf(text).intValue()));
hanleMap.put(Long.class, text -> (Long) Double.valueOf(text).longValue());
hanleMap.put(long.class, text -> (Long) Double.valueOf(text).longValue());
hanleMap.put(Double.class, text -> Double.valueOf(text));
hanleMap.put(double.class, text -> Double.valueOf(text));
hanleMap.put(Float.class, text -> (Float) Double.valueOf(text).floatValue());
hanleMap.put(float.class, text -> (Float) Double.valueOf(text).floatValue());
hanleMap.put(Boolean.class, text -> Boolean.valueOf(text));
hanleMap.put(boolean.class, text -> Boolean.valueOf(text));
hanleMap.put(Short.class, text -> (Short) Double.valueOf(text).shortValue());
hanleMap.put(short.class, text -> (Short) Double.valueOf(text).shortValue());
//hanleMap.put(String.class, text -> text);
hanleMap.put(Date.class, text -> {
try {
return Config.getDataFormat().parse(text);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
hanleMap.put(Calendar.class, text -> {
try {
Calendar instance = Calendar.getInstance();
instance.setTime(Config.getDataFormat().parse(text));
return instance;
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
//需要将数据处理为一个map
Map handle(Map> map) {
//根节点
Root root = new Root();
List leafs = new ArrayList<>();
map.forEach((k, v) -> {
H l = root;
String[] split = k.split("\\.");
StringBuilder n = new StringBuilder();
//找到最后一个节点
for (String s : split) {
l = l.getSub(s);
n.append(s);
l.mappingTypeExp = n.toString().replaceAll("(?<=\\[)[^\\[\\]]*(?=])", "");
n.append(".");
}
l.valueHolders = v;
Class> aClass = entityMapping.get(l.mappingTypeExp);
if (aClass != null) {
ValueHanle hanle = hanleMap.get(aClass);
if (hanle != null) {
v.forEach(d -> {
Object value = d.getValue();
if (value != null) {
String text = (String) value;
d.setValue(hanle.hanle(text));
}
});
}
}
leafs.add(l);
});
//遍历所有叶子节点
for (H leaf : leafs) {
leaf.transmit();
}
return root.r;
}
private class Root extends H {
private Map r = new HashMap<>();
@Override
void transmit() {
for (H value : subs.values()) {
int sum = 0;
for (ValueHolder holder : value.valueHolders) {
sum += holder.getRow();
}
value.forward(r, sum);
}
}
}
private class H {
private String name;
private String setterMethodName;
void setName(String name) {
this.name = name;
this.setterMethodName = setterName(name);
}
private String exp;
//用于映射实体的表达式
private String mappingTypeExp;
//变化的自变量,如果存在表明是一个数组元素
private String independent;
//父级节点
private H parent;
//模板中变量数通常不多
Map subs;
//值占位符
private List valueHolders;
H getSub(String exp) {
if (subs == null) {
subs = new HashMap<>();
}
return subs.computeIfAbsent(exp, k -> {
H h = new H();
StringUtils.SubStringResult string = StringUtils.pairingSubString(exp, 0, '[', ']');
if (string == null) {
h.setName(exp);
h.exp = exp;
} else {
String name = exp.substring(0, string.getStart());
String ind = exp.substring(string.getStart() + 1, string.getEnd() - 1);
h.setName(name);
//TODO 将数组中的自变量擦除
h.exp = exp;
h.independent = ind;
}
h.parent = H.this;
return h;
});
}
//下一轮的开始索引位置
private int index = 0;
private List