diff --git a/pom.xml b/pom.xml index 641dd476..06a43371 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 2.2.7 + 3.0.0-beta1 jar easyexcel @@ -16,7 +16,7 @@ UTF-8 - 1.6 + 1.8 true true @@ -60,22 +60,22 @@ org.apache.poi poi - 3.17 + 4.1.2 org.apache.poi poi-ooxml - 3.17 + 4.1.2 org.apache.poi poi-ooxml-schemas - 3.17 + 4.1.2 cglib cglib - 3.1 + 3.3.0 org.slf4j @@ -85,7 +85,7 @@ org.ehcache ehcache - 3.4.0 + 3.8.1 @@ -179,7 +179,7 @@ com.alibaba.p3c p3c-pmd - 1.3.6 + 2.1.1 @@ -187,8 +187,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 + 1.8 + 1.8 diff --git a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java index 78b57e0a..000e298d 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java @@ -17,6 +17,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.read.metadata.holder.ReadHolder; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.util.ConverterUtils; +import com.alibaba.excel.util.FieldUtils; import net.sf.cglib.beans.BeanMap; @@ -124,7 +125,7 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener excelContentProperty, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration(), context.readRowHolder().getRowIndex(), index); if (value != null) { - map.put(excelContentProperty.getField().getName(), value); + map.put(FieldUtils.resolveCglibFieldName(excelContentProperty.getField()), value); } } BeanMap.create(resultModel).putAll(map); diff --git a/src/main/java/com/alibaba/excel/util/FieldUtils.java b/src/main/java/com/alibaba/excel/util/FieldUtils.java new file mode 100644 index 00000000..1a4d5287 --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/FieldUtils.java @@ -0,0 +1,51 @@ +package com.alibaba.excel.util; + +import java.lang.reflect.Field; + +/** + * Field utils + * + * @author Jiaju Zhuang + **/ +public class FieldUtils { + + private static final int START_RESOLVE_FIELD_LENGTH = 2; + + /** + * Parsing the name matching cglib。 + *
    + *
      null -> null
    + *
      string1 -> string1
    + *
      String2 -> string2
    + *
      sTring3 -> STring3
    + *
      STring4 -> STring4
    + *
      STRING5 -> STRING5
    + *
      STRing6 -> STRing6
    + *
+ * + * @param field field + * @return field name. + */ + public static String resolveCglibFieldName(Field field) { + if (field == null) { + return null; + } + String fieldName = field.getName(); + if (StringUtils.isBlank(fieldName) || fieldName.length() < START_RESOLVE_FIELD_LENGTH) { + return fieldName; + } + char firstChar = fieldName.charAt(0); + char secondChar = fieldName.charAt(1); + if (Character.isUpperCase(firstChar) == Character.isUpperCase(secondChar)) { + return fieldName; + } + if (Character.isUpperCase(firstChar)) { + return buildFieldName(Character.toLowerCase(firstChar), fieldName); + } + return buildFieldName(Character.toUpperCase(firstChar), fieldName); + } + + private static String buildFieldName(char firstChar, String fieldName) { + return firstChar + fieldName.substring(1); + } +} diff --git a/src/main/java/com/alibaba/excel/util/StringUtils.java b/src/main/java/com/alibaba/excel/util/StringUtils.java index 948ae652..a67e46be 100644 --- a/src/main/java/com/alibaba/excel/util/StringUtils.java +++ b/src/main/java/com/alibaba/excel/util/StringUtils.java @@ -6,11 +6,67 @@ package com.alibaba.excel.util; * @author jipengfei */ public class StringUtils { + private StringUtils() {} + + /** + * A String for a space character. + */ + public static final String SPACE = " "; + + /** + * The empty String {@code ""}. + */ public static final String EMPTY = ""; - private StringUtils() {} + /** + *

Checks if a CharSequence is empty ("") or null.

+ * + *
+     * StringUtils.isEmpty(null)      = true
+     * StringUtils.isEmpty("")        = true
+     * StringUtils.isEmpty(" ")       = false
+     * StringUtils.isEmpty("bob")     = false
+     * StringUtils.isEmpty("  bob  ") = false
+     * 
+ * + *

NOTE: This method changed in Lang version 2.0. + * It no longer trims the CharSequence. + * That functionality is available in isBlank().

+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is empty or null + */ + public static boolean isEmpty(final CharSequence cs) { + return cs == null || cs.length() == 0; + } - public static boolean isEmpty(Object str) { - return (str == null || EMPTY.equals(str)); + /** + *

Checks if a CharSequence is empty (""), null or whitespace only.

+ * + *

Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.isBlank(null)      = true
+     * StringUtils.isBlank("")        = true
+     * StringUtils.isBlank(" ")       = true
+     * StringUtils.isBlank("bob")     = false
+     * StringUtils.isBlank("  bob  ") = false
+     * 
+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is null, empty or whitespace only + */ + public static boolean isBlank(final CharSequence cs) { + int strLen; + if (cs == null || (strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; } + } diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java index 9f229029..832cbb8a 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java @@ -8,9 +8,6 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; - import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.metadata.CellData; @@ -18,15 +15,16 @@ import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.CollectionUtils; +import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WriteHandlerUtils; -import com.alibaba.excel.write.metadata.WriteWorkbook; -import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; import com.alibaba.excel.write.metadata.holder.WriteHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import net.sf.cglib.beans.BeanMap; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; /** * Add the data into excel @@ -67,7 +65,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), n); WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE); if (oneRowData instanceof List) { - addBasicTypeToExcel((List) oneRowData, row, relativeRowIndex); + addBasicTypeToExcel((List)oneRowData, row, relativeRowIndex); } else { addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap); } @@ -127,7 +125,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { for (Map.Entry entry : contentPropertyMap.entrySet()) { cellIndex = entry.getKey(); ExcelContentProperty excelContentProperty = entry.getValue(); - String name = excelContentProperty.getField().getName(); + String name = FieldUtils.resolveCglibFieldName(excelContentProperty.getField()); if (!beanMap.containsKey(name)) { continue; } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelData.java b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelData.java new file mode 100644 index 00000000..dd010fc7 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelData.java @@ -0,0 +1,16 @@ +package com.alibaba.easyexcel.test.core.noncamel; + +import lombok.Data; + +/** + * @author Jiaju Zhuang + */ +@Data +public class UnCamelData { + private String string1; + private String String2; + private String sTring3; + private String STring4; + private String STRING5; + private String STRing6; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java new file mode 100644 index 00000000..2f36d665 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java @@ -0,0 +1,49 @@ +package com.alibaba.easyexcel.test.core.noncamel; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.fastjson.JSON; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; + +/** + * @author Jiaju Zhuang + */ +@Slf4j +public class UnCamelDataListener extends AnalysisEventListener { + List list = new ArrayList<>(); + + @Override + public void invokeHeadMap(Map headMap, AnalysisContext context) { + log.debug("Head is:{}", JSON.toJSONString(headMap)); + Assert.assertEquals(headMap.get(0), "string1"); + Assert.assertEquals(headMap.get(1), "String2"); + Assert.assertEquals(headMap.get(2), "sTring3"); + Assert.assertEquals(headMap.get(3), "STring4"); + Assert.assertEquals(headMap.get(4), "STRING5"); + Assert.assertEquals(headMap.get(5), "STRing6"); + } + + @Override + public void invoke(UnCamelData data, AnalysisContext context) { + list.add(data); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + Assert.assertEquals(list.size(), 10); + UnCamelData unCamelData = list.get(0); + Assert.assertEquals(unCamelData.getString1(), "string1"); + Assert.assertEquals(unCamelData.getString2(), "string2"); + Assert.assertEquals(unCamelData.getSTring3(), "string3"); + Assert.assertEquals(unCamelData.getSTring4(), "string4"); + Assert.assertEquals(unCamelData.getSTRING5(), "string5"); + Assert.assertEquals(unCamelData.getSTRing6(), "string6"); + log.debug("First row:{}", JSON.toJSONString(list.get(0))); + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataTest.java new file mode 100644 index 00000000..689c9f8a --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataTest.java @@ -0,0 +1,59 @@ +package com.alibaba.easyexcel.test.core.noncamel; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; + +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +/** + * @author Jiaju Zhuang + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class UnCamelDataTest { + + private static File file07; + private static File file03; + + @BeforeClass + public static void init() { + file07 = TestFileUtil.createNewFile("unCame07.xlsx"); + file03 = TestFileUtil.createNewFile("unCame03.xls"); + } + + @Test + public void t01ReadAndWrite07() { + readAndWrite(file07); + } + + @Test + public void t02ReadAndWrite03() { + readAndWrite(file03); + } + + private void readAndWrite(File file) { + EasyExcel.write(file, UnCamelData.class).sheet().doWrite(data()); + EasyExcel.read(file, UnCamelData.class, new UnCamelDataListener()).sheet().doRead(); + } + + private List data() { + List list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + UnCamelData unCamelData = new UnCamelData(); + unCamelData.setString1("string1"); + unCamelData.setString2("string2"); + unCamelData.setSTring3("string3"); + unCamelData.setSTring4("string4"); + unCamelData.setSTRING5("string5"); + unCamelData.setSTRing6("string6"); + list.add(unCamelData); + } + return list; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/CamlData.java b/src/test/java/com/alibaba/easyexcel/test/temp/CamlData.java new file mode 100644 index 00000000..9c3f39e4 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/CamlData.java @@ -0,0 +1,18 @@ +package com.alibaba.easyexcel.test.temp; + +import lombok.Data; + +/** + * TODO + * + * @author 是仪 + */ +@Data +public class CamlData { + private String string1; + private String String2; + private String sTring3; + private String STring4; + private String STRING5; + private String STRing6; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java index c4331b1e..e5d7dfc3 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java @@ -2,14 +2,15 @@ package com.alibaba.easyexcel.test.temp; import java.util.List; +import com.alibaba.excel.EasyExcel; +import com.alibaba.fastjson.JSON; + +import net.sf.cglib.core.DebuggingClassWriter; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.alibaba.excel.EasyExcel; -import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSON; +import org.springframework.cglib.beans.BeanMap; /** * 临时测试 @@ -27,4 +28,24 @@ public class Xls03Test { LOGGER.info("返回数据:{}", JSON.toJSONString(data)); } } + + @Test + public void test2() { + System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); + System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, + "/Users/zhuangjiaju/IdeaProjects/easyexcel/target"); + + CamlData camlData = new CamlData(); + //camlData.setTest("test2"); + //camlData.setAEst("test3"); + //camlData.setTEST("test4"); + + BeanMap beanMap = BeanMap.create(camlData); + + LOGGER.info("test:{}", beanMap.get("test")); + LOGGER.info("test:{}", beanMap.get("Test")); + LOGGER.info("test:{}", beanMap.get("TEst")); + LOGGER.info("test:{}", beanMap.get("TEST")); + + } } diff --git a/update.md b/update.md index d7a96f7c..2bc6813b 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,10 @@ +# 3.0.0-beta1 +* 升级jdk8 不再支持jdk6 jdk7 +* 升级poi 到 4.1.2 +* 升级cglib 到 3.3.0 +* 升级ehcache 到 3.8.1 +* 支持非驼峰的字段读写 + # 2.2.7 * 修改07在特殊情况下用`String`接收数字会丢小数位的bug