diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/export/base/ExportBase.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/export/base/ExportBase.java index 7ff050a..464b3a3 100644 --- a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/export/base/ExportBase.java +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/export/base/ExportBase.java @@ -34,6 +34,7 @@ import org.jeecgframework.poi.excel.annotation.ExcelEntity; import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity; import org.jeecgframework.poi.handler.inter.IExcelDataHandler; import org.jeecgframework.poi.util.PoiPublicUtil; +import org.jeecgframework.poi.util.PoiReflectorUtil; /** * 导出基础处理,不设计POI,只设计对象,保证复用性 @@ -122,7 +123,7 @@ public class ExportBase { excelEntity = new ExcelExportEntity(); excelEntity.setName(getExcelName(excel.name(), targetId)); excelEntity.setOrderNum(getCellOrder(excel.orderNum(), targetId)); - excelEntity.setMethod(PoiPublicUtil.getMethod(field.getName(), pojoClass)); + excelEntity.setMethod(PoiReflectorUtil.fromCache(pojoClass).getGetMethod(field.getName())); excelEntity.setList(list); excelParams.add(excelEntity); } else { @@ -130,7 +131,7 @@ public class ExportBase { if (getMethods != null) { newMethods.addAll(getMethods); } - newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass)); + newMethods.add(PoiReflectorUtil.fromCache(pojoClass).getGetMethod(field.getName())); ExcelEntity excel = field.getAnnotation(ExcelEntity.class); getAllExcelField(exclusions, StringUtils.isNotEmpty(excel.id()) ? excel.id() : targetId, PoiPublicUtil.getClassFields(field.getType()), excelParams, @@ -237,8 +238,7 @@ public class ExportBase { : excel.format()); excelEntity.setStatistics(excel.isStatistics()); excelEntity.setHyperlink(excel.isHyperlink()); - String fieldname = field.getName(); - excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass)); + excelEntity.setMethod(PoiReflectorUtil.fromCache(pojoClass).getGetMethod(field.getName())); } /** diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/ExcelImportServer.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/ExcelImportServer.java index 7ba1826..de78028 100644 --- a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/ExcelImportServer.java +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/ExcelImportServer.java @@ -55,6 +55,7 @@ import org.jeecgframework.poi.excel.imports.verifys.VerifyHandlerServer; import org.jeecgframework.poi.exception.excel.ExcelImportException; import org.jeecgframework.poi.exception.excel.enums.ExcelImportEnum; import org.jeecgframework.poi.util.PoiPublicUtil; +import org.jeecgframework.poi.util.PoiReflectorUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,8 +101,7 @@ public class ExcelImportServer extends ImportBaseService { Map titlemap, String targetId, Map pictures, ImportParams params) throws Exception { - Collection collection = (Collection) PoiPublicUtil.getMethod(param.getName(), - object.getClass()).invoke(object, new Object[] {}); + Collection collection = (Collection) PoiReflectorUtil.fromCache(object.getClass()).getValue(object, param.getName()); Object entity = PoiPublicUtil.createObject(param.getType(), targetId); String picId; boolean isUsed = false;// 是否需要加上这个对象 diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/base/ImportBaseService.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/base/ImportBaseService.java index 333a9da..c6f2cc4 100644 --- a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/base/ImportBaseService.java +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/base/ImportBaseService.java @@ -39,6 +39,7 @@ import org.jeecgframework.poi.excel.entity.params.ExcelCollectionParams; import org.jeecgframework.poi.excel.entity.params.ExcelImportEntity; import org.jeecgframework.poi.excel.entity.params.ExcelVerifyEntity; import org.jeecgframework.poi.util.PoiPublicUtil; +import org.jeecgframework.poi.util.PoiReflectorUtil; /** * 导入基础和,普通方法和Sax共用 @@ -146,7 +147,7 @@ public class ImportBaseService { if (getMethods != null) { newMethods.addAll(getMethods); } - newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass)); + newMethods.add(PoiReflectorUtil.fromCache(pojoClass).getGetMethod(field.getName())); getAllExcelField(targetId, PoiPublicUtil.getClassFields(field.getType()), excelParams, excelCollection, field.getType(), newMethods); } @@ -171,7 +172,7 @@ public class ImportBaseService { Excel excel, Class pojoClass) throws Exception { excelEntity.setName(getExcelName(excel.name(), targetId)); String fieldname = field.getName(); - excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass, field.getType())); + excelEntity.setMethod(PoiReflectorUtil.fromCache(pojoClass).getSetMethod(fieldname)); if (StringUtils.isNotEmpty(excel.importFormat())) { excelEntity.setFormat(excel.importFormat()); } else { @@ -196,7 +197,7 @@ public class ImportBaseService { newMethods.addAll(getMethods); } newMethods - .add(PoiPublicUtil.getMethod(field.getName(), pojoClass, field.getType())); + .add(PoiReflectorUtil.fromCache(pojoClass).getSetMethod(field.getName())); getExcelFieldList(targetId, PoiPublicUtil.getClassFields(field.getType()), field.getType(), temp, newMethods); } diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/sax/parse/SaxRowRead.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/sax/parse/SaxRowRead.java index 1223b62..e977fbc 100644 --- a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/sax/parse/SaxRowRead.java +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/imports/sax/parse/SaxRowRead.java @@ -33,6 +33,7 @@ import org.jeecgframework.poi.excel.imports.base.ImportBaseService; import org.jeecgframework.poi.exception.excel.ExcelImportException; import org.jeecgframework.poi.handler.inter.IExcelReadRowHanlder; import org.jeecgframework.poi.util.PoiPublicUtil; +import org.jeecgframework.poi.util.PoiReflectorUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -170,8 +171,7 @@ public class SaxRowRead extends ImportBaseService implements ISaxRowRead { private void addListContinue(Object object, ExcelCollectionParams param, List datas, Map titlemap, String targetId, ImportParams params) throws Exception { - Collection collection = (Collection) PoiPublicUtil.getMethod(param.getName(), - object.getClass()).invoke(object, new Object[] {}); + Collection collection = (Collection) PoiReflectorUtil.fromCache(pojoClass).getValue(object, param.getName()); Object entity = PoiPublicUtil.createObject(param.getType(), targetId); boolean isUsed = false;// 是否需要加上这个对象 for (int i = 0; i < datas.size(); i++) { diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiPublicUtil.java b/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiPublicUtil.java index ab7229f..f8ecb95 100644 --- a/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiPublicUtil.java +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiPublicUtil.java @@ -15,6 +15,8 @@ */ package org.jeecgframework.poi.util; +import static org.jeecgframework.poi.util.PoiElUtil.*; + import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -49,7 +51,6 @@ import org.jeecgframework.poi.excel.annotation.Excel; import org.jeecgframework.poi.excel.annotation.ExcelCollection; import org.jeecgframework.poi.excel.annotation.ExcelEntity; import org.jeecgframework.poi.excel.annotation.ExcelIgnore; -import org.jeecgframework.poi.excel.entity.vo.PoiBaseConstants; import org.jeecgframework.poi.word.entity.WordImageEntity; import org.jeecgframework.poi.word.entity.params.ExcelListEntity; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; @@ -86,7 +87,6 @@ public final class PoiPublicUtil { */ public static Object createObject(Class clazz, String targetId) { Object obj = null; - Method setMethod; try { if (clazz.equals(Map.class)) { return new HashMap(); @@ -99,11 +99,9 @@ public final class PoiPublicUtil { } if (isCollection(field.getType())) { ExcelCollection collection = field.getAnnotation(ExcelCollection.class); - setMethod = getMethod(field.getName(), clazz, field.getType()); - setMethod.invoke(obj, collection.type().newInstance()); + PoiReflectorUtil.fromCache(clazz).setValue(obj , field.getName(), collection.type().newInstance()); } else if (!isJavaClass(field)) { - setMethod = getMethod(field.getName(), clazz, field.getType()); - setMethod.invoke(obj, createObject(field.getType(), targetId)); + PoiReflectorUtil.fromCache(clazz).setValue(obj , field.getName(), createObject(field.getType(), targetId)); } } @@ -155,45 +153,6 @@ public final class PoiPublicUtil { return strFileExtendName; } - /** - * 获取GET方法 - * - * @param name - * @param pojoClass - * @return - * @throws Exception - */ - public static Method getMethod(String name, Class pojoClass) throws Exception { - StringBuffer getMethodName = new StringBuffer(PoiBaseConstants.GET); - getMethodName.append(name.substring(0, 1).toUpperCase()); - getMethodName.append(name.substring(1)); - Method method = null; - try { - method = pojoClass.getMethod(getMethodName.toString(), new Class[] {}); - } catch (Exception e) { - method = pojoClass.getMethod( - getMethodName.toString().replace(PoiBaseConstants.GET, PoiBaseConstants.IS), - new Class[] {}); - } - return method; - } - - /** - * 获取SET方法 - * - * @param name - * @param pojoClass - * @param type - * @return - * @throws Exception - */ - public static Method getMethod(String name, Class pojoClass, Class type) throws Exception { - StringBuffer getMethodName = new StringBuffer(PoiBaseConstants.SET); - getMethodName.append(name.substring(0, 1).toUpperCase()); - getMethodName.append(name.substring(1)); - return pojoClass.getMethod(getMethodName.toString(), new Class[] { type }); - } - /** * 获取Excel2003图片 * @@ -406,7 +365,7 @@ public final class PoiPublicUtil { if (object instanceof Map) { return ((Map) object).get(params); } - return getMethod(params, object.getClass()).invoke(object, new Object[] {}); + return PoiReflectorUtil.fromCache(object.getClass()).getValue(object, params); } /** @@ -418,17 +377,17 @@ public final class PoiPublicUtil { */ public static Object getRealValue(String currentText, Map map) throws Exception { String params = ""; - while (currentText.indexOf("{{") != -1) { + while (currentText.indexOf(START_STR) != -1) { params = currentText - .substring(currentText.indexOf("{{") + 2, currentText.indexOf("}}")); - Object obj = getParamsValue(params.trim(), map); + .substring(currentText.indexOf(START_STR) + 2, currentText.indexOf(END_STR)); + Object obj = PoiElUtil.eval(params.trim(), map); //判断图片或者是集合 if (obj instanceof WordImageEntity || obj instanceof List || obj instanceof ExcelListEntity) { return obj; } else { - currentText = currentText.replace("{{" + params + "}}", obj.toString()); + currentText = currentText.replace(START_STR + params + END_STR, obj.toString()); } } return currentText; @@ -455,7 +414,7 @@ public final class PoiPublicUtil { if (object instanceof Map) { object = ((Map) object).get(paramsArr[index]); } else { - object = getMethod(paramsArr[index], object.getClass()).invoke(object, new Object[] {}); + object = PoiReflectorUtil.fromCache(object.getClass()).getValue(object, paramsArr[index]); } return (index == paramsArr.length - 1) ? (object == null ? "" : object) : getValueDoWhile( object, paramsArr, ++index); diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiReflectorUtil.java b/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiReflectorUtil.java new file mode 100644 index 0000000..1499eff --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiReflectorUtil.java @@ -0,0 +1,356 @@ +package org.jeecgframework.poi.util; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ReflectPermission; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 反射工具类,缓存读取的class信息,省的一直获取 + * @author JueYue + * 参考的 mybatis的Reflector + */ +public final class PoiReflectorUtil { + + private static final Map, PoiReflectorUtil> CACHE_REFLECTOR = new ConcurrentHashMap, PoiReflectorUtil>(); + + private Map getMethods = new HashMap(); + private Map setMethods = new HashMap(); + private List fieldList = new ArrayList(); + + private Class type; + + private PoiReflectorUtil(Class clazz) { + addGetMethods(clazz); + addFields(clazz); + addSetMethods(clazz); + } + + public static PoiReflectorUtil forClass(Class clazz) { + return new PoiReflectorUtil(clazz); + } + + public static PoiReflectorUtil fromCache(Class clazz) { + if (!CACHE_REFLECTOR.containsKey(clazz)) { + CACHE_REFLECTOR.put(clazz, new PoiReflectorUtil(clazz)); + } + return CACHE_REFLECTOR.get(clazz); + } + + private void addGetMethods(Class cls) { + Map> conflictingGetters = new HashMap>(); + Method[] methods = getClassMethods(cls); + for (Method method : methods) { + String name = method.getName(); + if (name.startsWith("get") && name.length() > 3) { + if (method.getParameterTypes().length == 0) { + name = methodToProperty(name); + addMethodConflict(conflictingGetters, name, method); + } + } else if (name.startsWith("is") && name.length() > 2) { + if (method.getParameterTypes().length == 0) { + name = methodToProperty(name); + addMethodConflict(conflictingGetters, name, method); + } + } + } + resolveGetterConflicts(conflictingGetters); + } + + private void resolveGetterConflicts(Map> conflictingGetters) { + for (String propName : conflictingGetters.keySet()) { + List getters = conflictingGetters.get(propName); + Iterator iterator = getters.iterator(); + Method firstMethod = iterator.next(); + if (getters.size() == 1) { + addGetMethod(propName, firstMethod); + } else { + Method getter = firstMethod; + Class getterType = firstMethod.getReturnType(); + while (iterator.hasNext()) { + Method method = iterator.next(); + Class methodType = method.getReturnType(); + if (methodType.equals(getterType)) { + throw new RuntimeException( + "Illegal overloaded getter method with ambiguous type for property " + + propName + " in class " + firstMethod.getDeclaringClass() + + ". This breaks the JavaBeans " + + "specification and can cause unpredicatble results."); + } else if (methodType.isAssignableFrom(getterType)) { + // OK getter type is descendant + } else if (getterType.isAssignableFrom(methodType)) { + getter = method; + getterType = methodType; + } else { + throw new RuntimeException( + "Illegal overloaded getter method with ambiguous type for property " + + propName + " in class " + firstMethod.getDeclaringClass() + + ". This breaks the JavaBeans " + + "specification and can cause unpredicatble results."); + } + } + addGetMethod(propName, getter); + } + } + } + + private void addGetMethod(String name, Method method) { + if (isValidPropertyName(name)) { + getMethods.put(name, method); + } + } + + private void addSetMethods(Class cls) { + Map> conflictingSetters = new HashMap>(); + Method[] methods = getClassMethods(cls); + for (Method method : methods) { + String name = method.getName(); + if (name.startsWith("set") && name.length() > 3) { + if (method.getParameterTypes().length == 1) { + name = methodToProperty(name); + addMethodConflict(conflictingSetters, name, method); + } + } + } + resolveSetterConflicts(conflictingSetters); + } + + private static String methodToProperty(String name) { + if (name.startsWith("is")) { + name = name.substring(2); + } else if (name.startsWith("get") || name.startsWith("set")) { + name = name.substring(3); + } else { + throw new RuntimeException("Error parsing property name '" + name + + "'. Didn't start with 'is', 'get' or 'set'."); + } + + if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) { + name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1); + } + + return name; + } + + private void addMethodConflict(Map> conflictingMethods, String name, + Method method) { + List list = conflictingMethods.get(name); + if (list == null) { + list = new ArrayList(); + conflictingMethods.put(name, list); + } + list.add(method); + } + + private void resolveSetterConflicts(Map> conflictingSetters) { + for (String propName : conflictingSetters.keySet()) { + List setters = conflictingSetters.get(propName); + Method firstMethod = setters.get(0); + if (setters.size() == 1) { + addSetMethod(propName, firstMethod); + } else { + Iterator methods = setters.iterator(); + Method setter = null; + while (methods.hasNext()) { + Method method = methods.next(); + if (method.getParameterTypes().length == 1) { + setter = method; + break; + } + } + if (setter == null) { + throw new RuntimeException( + "Illegal overloaded setter method with ambiguous type for property " + + propName + " in class " + firstMethod.getDeclaringClass() + + ". This breaks the JavaBeans " + + "specification and can cause unpredicatble results."); + } + addSetMethod(propName, setter); + } + } + } + + private void addSetMethod(String name, Method method) { + if (isValidPropertyName(name)) { + setMethods.put(name, method); + } + } + + private void addFields(Class clazz) { + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + if (canAccessPrivateMethods()) { + try { + field.setAccessible(true); + } catch (Exception e) { + // Ignored. This is only a final precaution, nothing we can do. + } + } + if (field.isAccessible() && !field.getName().equalsIgnoreCase("serialVersionUID")) { + this.fieldList.add(field); + } + } + if (clazz.getSuperclass() != null) { + addFields(clazz.getSuperclass()); + } + } + + private boolean isValidPropertyName(String name) { + return !(name.startsWith("$") || "serialVersionUID".equals(name) || "class".equals(name)); + } + + /* + * This method returns an array containing all methods + * declared in this class and any superclass. + * We use this method, instead of the simpler Class.getMethods(), + * because we want to look for private methods as well. + * + * @param cls The class + * @return An array containing all methods in this class + */ + private Method[] getClassMethods(Class cls) { + HashMap uniqueMethods = new HashMap(); + Class currentClass = cls; + while (currentClass != null) { + addUniqueMethods(uniqueMethods, currentClass.getDeclaredMethods()); + + // we also need to look for interface methods - + // because the class may be abstract + Class[] interfaces = currentClass.getInterfaces(); + for (Class anInterface : interfaces) { + addUniqueMethods(uniqueMethods, anInterface.getMethods()); + } + + currentClass = currentClass.getSuperclass(); + } + + Collection methods = uniqueMethods.values(); + + return methods.toArray(new Method[methods.size()]); + } + + private void addUniqueMethods(HashMap uniqueMethods, Method[] methods) { + for (Method currentMethod : methods) { + if (!currentMethod.isBridge()) { + String signature = getSignature(currentMethod); + // check to see if the method is already known + // if it is known, then an extended class must have + // overridden a method + if (!uniqueMethods.containsKey(signature)) { + if (canAccessPrivateMethods()) { + try { + currentMethod.setAccessible(true); + } catch (Exception e) { + // Ignored. This is only a final precaution, nothing we can do. + } + } + + uniqueMethods.put(signature, currentMethod); + } + } + } + } + + private String getSignature(Method method) { + StringBuilder sb = new StringBuilder(); + Class returnType = method.getReturnType(); + if (returnType != null) { + sb.append(returnType.getName()).append('#'); + } + sb.append(method.getName()); + Class[] parameters = method.getParameterTypes(); + for (int i = 0; i < parameters.length; i++) { + if (i == 0) { + sb.append(':'); + } else { + sb.append(','); + } + sb.append(parameters[i].getName()); + } + return sb.toString(); + } + + private boolean canAccessPrivateMethods() { + try { + SecurityManager securityManager = System.getSecurityManager(); + if (null != securityManager) { + securityManager.checkPermission(new ReflectPermission("suppressAccessChecks")); + } + } catch (SecurityException e) { + return false; + } + return true; + } + + public Method getGetMethod(String propertyName) { + Method method = getMethods.get(propertyName); + if (method == null) { + throw new RuntimeException("There is no getter for property named '" + propertyName + + "' in '" + type + "'"); + } + return method; + } + + public Method getSetMethod(String propertyName) { + Method method = setMethods.get(propertyName); + if (method == null) { + throw new RuntimeException("There is no getter for property named '" + propertyName + + "' in '" + type + "'"); + } + return method; + } + + /** + * 获取field 值 + * @param obj + * @param property + * @return + */ + public Object getValue(Object obj, String property) { + Object value = null; + Method m = getMethods.get(property); + if (m != null) { + try { + value = m.invoke(obj, new Object[] {}); + } catch (Exception ex) { + } + } + return value; + } + + /** + * 设置field值 + * @param obj 对象 + * @param property + * @param object 属性值 + * @return + */ + public boolean setValue(Object obj, String property, Object object) { + Method m = setMethods.get(property); + if (m != null) { + try { + m.invoke(obj, object); + return true; + } catch (Exception ex) { + return false; + } + } + return false; + } + + public Map getGetMethods() { + return getMethods; + } + + public List getFieldList() { + return fieldList; + } + +} diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/word/parse/ParseWord07.java b/easypoi-base/src/main/java/org/jeecgframework/poi/word/parse/ParseWord07.java index 94e8995..57820ae 100644 --- a/easypoi-base/src/main/java/org/jeecgframework/poi/word/parse/ParseWord07.java +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/word/parse/ParseWord07.java @@ -15,7 +15,10 @@ */ package org.jeecgframework.poi.word.parse; +import static org.jeecgframework.poi.util.PoiElUtil.*; + import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -64,15 +67,15 @@ public class ParseWord07 { Object[] isAndType = PoiPublicUtil.getIsAndType(obj); String picId; try { - picId = currentRun.getParagraph().getDocument() - .addPictureData((byte[]) isAndType[0], (Integer) isAndType[1]); + picId = currentRun.getParagraph().getDocument().addPictureData((byte[]) isAndType[0], + (Integer) isAndType[1]); ((MyXWPFDocument) currentRun.getParagraph().getDocument()).createPicture(currentRun, - picId, - currentRun.getParagraph().getDocument() - .getNextPicNameNumber((Integer) isAndType[1]), obj.getWidth(), obj.getHeight()); + picId, currentRun.getParagraph().getDocument() + .getNextPicNameNumber((Integer) isAndType[1]), + obj.getWidth(), obj.getHeight()); } catch (Exception e) { - LOGGER.error(e.getMessage(),e); + LOGGER.error(e.getMessage(), e); } } @@ -108,12 +111,15 @@ public class ParseWord07 { * @return * @throws Exception */ - private Object checkThisTableIsNeedIterator(XWPFTableCell cell, Map map) - throws Exception { + private Object checkThisTableIsNeedIterator(XWPFTableCell cell, + Map map) throws Exception { String text = cell.getText().trim(); // 判断是不是迭代输出 - if (text.startsWith("{{") && text.endsWith("}}") && text.indexOf("in ") != -1) { - return PoiPublicUtil.getRealValue(text.replace("in ", "").trim(), map); + if (text != null && text.contains(FOREACH) && text.startsWith(START_STR)) { + text = text.replace(FOREACH_NOT_CREATE, EMPTY).replace(FOREACH_AND_SHIFT, EMPTY) + .replace(FOREACH, EMPTY).replace(START_STR, EMPTY); + String[] keys = text.replaceAll("\\s{1,}", " ").trim().split(" "); + return (Collection) PoiPublicUtil.getParamsValue(keys[0], map); } return null; } @@ -126,12 +132,12 @@ public class ParseWord07 { * @param paragraphs * @param map */ - private void parseAllParagraphic(List paragraphs, Map map) - throws Exception { + private void parseAllParagraphic(List paragraphs, + Map map) throws Exception { XWPFParagraph paragraph; for (int i = 0; i < paragraphs.size(); i++) { paragraph = paragraphs.get(i); - if (paragraph.getText().indexOf("{{") != -1) { + if (paragraph.getText().indexOf(START_STR) != -1) { parseThisParagraph(paragraph, map); } @@ -147,8 +153,8 @@ public class ParseWord07 { * @param paragraph * @param map */ - private void parseThisParagraph(XWPFParagraph paragraph, Map map) - throws Exception { + private void parseThisParagraph(XWPFParagraph paragraph, + Map map) throws Exception { XWPFRun run; XWPFRun currentRun = null;// 拿到的第一个run,用来set值,可以保存格式 String currentText = "";// 存放当前的text @@ -160,28 +166,28 @@ public class ParseWord07 { text = run.getText(0); if (StringUtils.isEmpty(text)) { continue; - }// 如果为空或者""这种这继续循环跳过 + } // 如果为空或者""这种这继续循环跳过 if (isfinde) { currentText += text; - if (currentText.indexOf("{{") == -1) { + if (currentText.indexOf(START_STR) == -1) { isfinde = false; runIndex.clear(); } else { runIndex.add(i); } - if (currentText.indexOf("}}") != -1) { + if (currentText.indexOf(END_STR) != -1) { changeValues(paragraph, currentRun, currentText, runIndex, map); currentText = ""; isfinde = false; } - } else if (text.indexOf("{") >= 0) {// 判断是不是开始 + } else if (text.indexOf(START_STR) >= 0) {// 判断是不是开始 currentText = text; isfinde = true; currentRun = run; } else { currentText = ""; } - if (currentText.indexOf("}}") != -1) { + if (currentText.indexOf(END_STR) != -1) { changeValues(paragraph, currentRun, currentText, runIndex, map); isfinde = false; } @@ -207,23 +213,17 @@ public class ParseWord07 { XWPFTableRow row; List cells; Object listobj; - ExcelEntityParse excelEntityParse = new ExcelEntityParse(); for (int i = 0; i < table.getNumberOfRows(); i++) { row = table.getRow(i); cells = row.getTableCells(); - if (cells.size() == 1) { - listobj = checkThisTableIsNeedIterator(cells.get(0), map); - if (listobj == null) { - parseThisRow(cells, map); - } else if (listobj instanceof ExcelListEntity) { - table.removeRow(i);// 删除这一行 - excelEntityParse.parseNextRowAndAddRow(table, i, (ExcelListEntity) listobj); - } else { - table.removeRow(i);// 删除这一行 - ExcelMapParse.parseNextRowAndAddRow(table, i, (List) listobj); - } - } else { + listobj = checkThisTableIsNeedIterator(cells.get(0), map); + if (listobj == null) { parseThisRow(cells, map); + } else if (listobj instanceof ExcelListEntity) { + table.removeRow(i);// 删除这一行 + new ExcelEntityParse().parseNextRowAndAddRow(table, i, (ExcelListEntity) listobj); + } else { + ExcelMapParse.parseNextRowAndAddRow(table, i, (List) listobj); } } } @@ -264,7 +264,7 @@ public class ParseWord07 { Iterator itTable = doc.getTablesIterator(); while (itTable.hasNext()) { table = itTable.next(); - if (table.getText().indexOf("{{") != -1) { + if (table.getText().indexOf(START_STR) != -1) { parseThisTable(table, map); } } diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/word/parse/excel/ExcelMapParse.java b/easypoi-base/src/main/java/org/jeecgframework/poi/word/parse/excel/ExcelMapParse.java index 74e731b..a507865 100644 --- a/easypoi-base/src/main/java/org/jeecgframework/poi/word/parse/excel/ExcelMapParse.java +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/word/parse/excel/ExcelMapParse.java @@ -15,12 +15,16 @@ */ package org.jeecgframework.poi.word.parse.excel; +import static org.jeecgframework.poi.util.PoiElUtil.*; + import java.util.List; +import java.util.Map; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import org.apache.poi.xwpf.usermodel.XWPFTableRow; -import org.jeecgframework.poi.util.PoiPublicUtil; + +import com.google.common.collect.Maps; /** * 处理和生成Map 类型的数据变成表格 @@ -43,7 +47,8 @@ public final class ExcelMapParse { String text; for (int i = 0; i < cells.size(); i++) { text = cells.get(i).getText(); - params[i] = text == null ? "" : text.trim().replace("{{", "").replace("}}", ""); + params[i] = text == null ? "" + : text.trim().replace(START_STR, EMPTY).replace(END_STR, EMPTY); } return params; } @@ -56,26 +61,30 @@ public final class ExcelMapParse { * @param table * @param listobj2 */ - public static void parseNextRowAndAddRow(XWPFTable table, int index, List list) - throws Exception { + public static void parseNextRowAndAddRow(XWPFTable table, int index, + List list) throws Exception { XWPFTableRow currentRow = table.getRow(index); String[] params = parseCurrentRowGetParams(currentRow); + String listname = params[0]; + boolean isCreate = !listname.contains(FOREACH_NOT_CREATE); + listname = listname.replace(FOREACH_NOT_CREATE, EMPTY).replace(FOREACH_AND_SHIFT, EMPTY) + .replace(FOREACH, EMPTY).replace(START_STR, EMPTY); + String[] keys = listname.replaceAll("\\s{1,}", " ").trim().split(" "); + params[0] = keys[1]; table.removeRow(index);// 移除这一行 int cellIndex = 0;// 创建完成对象一行好像多了一个cell + Map tempMap = Maps.newHashMap(); for (Object obj : list) { - currentRow = table.createRow(); + currentRow = isCreate ? table.createRow() : table.getRow(index++); + tempMap.put("t", obj); for (cellIndex = 0; cellIndex < currentRow.getTableCells().size(); cellIndex++) { - currentRow - .getTableCells() - .get(cellIndex) - .setText( - PoiPublicUtil.getValueDoWhile(obj, params[cellIndex].split("\\."), 0) - .toString()); + String val = eval(params[cellIndex], tempMap).toString(); + currentRow.getTableCells().get(cellIndex).setText(val); } + for (; cellIndex < params.length; cellIndex++) { - currentRow.createCell().setText( - PoiPublicUtil.getValueDoWhile(obj, params[cellIndex].split("\\."), 0) - .toString()); + String val = eval(params[cellIndex], tempMap).toString(); + currentRow.createCell().setText(val); } }