Browse Source

支持非驼峰的字段读写

pull/1863/head
是仪 4 years ago
parent
commit
412a8bd2d1
  1. 20
      pom.xml
  2. 3
      src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
  3. 51
      src/main/java/com/alibaba/excel/util/FieldUtils.java
  4. 62
      src/main/java/com/alibaba/excel/util/StringUtils.java
  5. 10
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
  6. 16
      src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelData.java
  7. 49
      src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java
  8. 59
      src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataTest.java
  9. 18
      src/test/java/com/alibaba/easyexcel/test/temp/CamlData.java
  10. 29
      src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java
  11. 7
      update.md

20
pom.xml

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>2.2.7</version> <version>3.0.0-beta1</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>easyexcel</name> <name>easyexcel</name>
@ -16,7 +16,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.6</jdk.version> <jdk.version>1.8</jdk.version>
<gpg.skip>true</gpg.skip> <gpg.skip>true</gpg.skip>
<maven.javadoc.skip>true</maven.javadoc.skip> <maven.javadoc.skip>true</maven.javadoc.skip>
</properties> </properties>
@ -60,22 +60,22 @@
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId> <artifactId>poi</artifactId>
<version>3.17</version> <version>4.1.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId> <artifactId>poi-ooxml</artifactId>
<version>3.17</version> <version>4.1.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId> <artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version> <version>4.1.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cglib</groupId> <groupId>cglib</groupId>
<artifactId>cglib</artifactId> <artifactId>cglib</artifactId>
<version>3.1</version> <version>3.3.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
@ -85,7 +85,7 @@
<dependency> <dependency>
<groupId>org.ehcache</groupId> <groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId> <artifactId>ehcache</artifactId>
<version>3.4.0</version> <version>3.8.1</version>
</dependency> </dependency>
<!--test--> <!--test-->
<dependency> <dependency>
@ -179,7 +179,7 @@
<dependency> <dependency>
<groupId>com.alibaba.p3c</groupId> <groupId>com.alibaba.p3c</groupId>
<artifactId>p3c-pmd</artifactId> <artifactId>p3c-pmd</artifactId>
<version>1.3.6</version> <version>2.1.1</version>
</dependency> </dependency>
</dependencies> </dependencies>
</plugin> </plugin>
@ -187,8 +187,8 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<source>1.6</source> <source>1.8</source>
<target>1.6</target> <target>1.8</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>

3
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.holder.ReadHolder;
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
import com.alibaba.excel.util.ConverterUtils; import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.excel.util.FieldUtils;
import net.sf.cglib.beans.BeanMap; import net.sf.cglib.beans.BeanMap;
@ -124,7 +125,7 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener
excelContentProperty, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration(), excelContentProperty, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration(),
context.readRowHolder().getRowIndex(), index); context.readRowHolder().getRowIndex(), index);
if (value != null) { if (value != null) {
map.put(excelContentProperty.getField().getName(), value); map.put(FieldUtils.resolveCglibFieldName(excelContentProperty.getField()), value);
} }
} }
BeanMap.create(resultModel).putAll(map); BeanMap.create(resultModel).putAll(map);

51
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
* <ul>
* <ul>null -> null</ul>
* <ul>string1 -> string1</ul>
* <ul>String2 -> string2</ul>
* <ul>sTring3 -> STring3</ul>
* <ul>STring4 -> STring4</ul>
* <ul>STRING5 -> STRING5</ul>
* <ul>STRing6 -> STRing6</ul>
* </ul>
*
* @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);
}
}

62
src/main/java/com/alibaba/excel/util/StringUtils.java

@ -6,11 +6,67 @@ package com.alibaba.excel.util;
* @author jipengfei * @author jipengfei
*/ */
public class StringUtils { 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 = ""; public static final String EMPTY = "";
private StringUtils() {} /**
* <p>Checks if a CharSequence is empty ("") or null.</p>
*
* <pre>
* StringUtils.isEmpty(null) = true
* StringUtils.isEmpty("") = true
* StringUtils.isEmpty(" ") = false
* StringUtils.isEmpty("bob") = false
* StringUtils.isEmpty(" bob ") = false
* </pre>
*
* <p>NOTE: This method changed in Lang version 2.0.
* It no longer trims the CharSequence.
* That functionality is available in isBlank().</p>
*
* @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)); * <p>Checks if a CharSequence is empty (""), null or whitespace only.</p>
*
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isBlank(null) = true
* StringUtils.isBlank("") = true
* StringUtils.isBlank(" ") = true
* StringUtils.isBlank("bob") = false
* StringUtils.isBlank(" bob ") = false
* </pre>
*
* @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;
}
} }

10
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.Set;
import java.util.TreeMap; 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.context.WriteContext;
import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.metadata.CellData; 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.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.FieldUtils;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.util.WriteHandlerUtils; 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.WriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import net.sf.cglib.beans.BeanMap; 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 * Add the data into excel
@ -127,7 +125,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) { for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) {
cellIndex = entry.getKey(); cellIndex = entry.getKey();
ExcelContentProperty excelContentProperty = entry.getValue(); ExcelContentProperty excelContentProperty = entry.getValue();
String name = excelContentProperty.getField().getName(); String name = FieldUtils.resolveCglibFieldName(excelContentProperty.getField());
if (!beanMap.containsKey(name)) { if (!beanMap.containsKey(name)) {
continue; continue;
} }

16
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;
}

49
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<UnCamelData> {
List<UnCamelData> list = new ArrayList<>();
@Override
public void invokeHeadMap(Map<Integer, String> 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)));
}
}

59
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<UnCamelData> data() {
List<UnCamelData> 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;
}
}

18
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;
}

29
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 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.Ignore;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanMap;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
/** /**
* 临时测试 * 临时测试
@ -27,4 +28,24 @@ public class Xls03Test {
LOGGER.info("返回数据:{}", JSON.toJSONString(data)); 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"));
}
} }

7
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 # 2.2.7
* 修改07在特殊情况下用`String`接收数字会丢小数位的bug * 修改07在特殊情况下用`String`接收数字会丢小数位的bug

Loading…
Cancel
Save