Browse Source

[fix]fix potential type mismatches that could occur during property conversion.

pull/3920/head
Black Pan 8 months ago
parent
commit
f1e0638cdd
  1. 11
      easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
  2. 64
      easyexcel-core/src/main/java/com/alibaba/excel/util/BeanMapUtils.java
  3. 16
      easyexcel-core/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
  4. 11
      easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java
  5. 25
      easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue3913/CsbDataItemTest.java
  6. 41
      easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue3913/Issue3913Test.java
  7. 16
      easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java

11
easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java

@ -1,9 +1,5 @@
package com.alibaba.excel.read.listener;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.enums.HeadKindEnum;
@ -14,13 +10,16 @@ import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
import com.alibaba.excel.support.cglib.beans.BeanMap;
import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.MapUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
/**
* Convert to the object the user needs
@ -133,7 +132,7 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<
"Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e);
}
Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap();
BeanMap dataMap = BeanMapUtils.create(resultModel);
Map<String, Object> dataMap = BeanMapUtils.create(resultModel);
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Integer index = entry.getKey();
Head head = entry.getValue();

64
easyexcel-core/src/main/java/com/alibaba/excel/util/BeanMapUtils.java

@ -1,7 +1,8 @@
package com.alibaba.excel.util;
import com.alibaba.excel.support.cglib.beans.BeanMap;
import com.alibaba.excel.support.cglib.core.DefaultNamingPolicy;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* bean utils
@ -11,30 +12,63 @@ import com.alibaba.excel.support.cglib.core.DefaultNamingPolicy;
public class BeanMapUtils {
/**
* Helper method to create a new <code>BeanMap</code>. For finer
* Helper method to create a new <code>BeanMap</code>. For finer
* control over the generated instance, use a new instance of
* <code>BeanMap.Generator</code> instead of this static method.
*
* Custom naming policy to prevent null pointer exceptions.
* see: https://github.com/alibaba/easyexcel/issues/2064
* Uses getter methods to access field values, enhancing encapsulation.
* Handles exceptions more gracefully and ensures thread safety for map.
*
* @param bean the JavaBean underlying the map
* @return a new <code>BeanMap</code> instance
*/
public static BeanMap create(Object bean) {
BeanMap.Generator gen = new BeanMap.Generator();
gen.setBean(bean);
gen.setContextClass(bean.getClass());
gen.setNamingPolicy(EasyExcelNamingPolicy.INSTANCE);
return gen.create();
public static Map<String, Object> create(Object bean) {
// Create a map to store the bean's property names and their corresponding values
Map<String, Object> propertyMap = new HashMap<>();
// Iterate over all declared fields of the bean
for (Field field : bean.getClass().getDeclaredFields()) {
// Set the field accessible to be able to access private fields
field.setAccessible(true);
try {
// Get the field value using a getter method and put it into the map
Object fieldValue = getFieldValueUsingGetter(bean, field);
if (fieldValue != null) {
propertyMap.put(field.getName(), fieldValue);
}
} catch (Exception e) {
// Capture all exceptions that can occur during field access
e.printStackTrace();
}
}
// Return the map containing the bean's properties
return propertyMap;
}
public static class EasyExcelNamingPolicy extends DefaultNamingPolicy {
public static final EasyExcelNamingPolicy INSTANCE = new EasyExcelNamingPolicy();
@Override
protected String getTag() {
return "ByEasyExcelCGLIB";
private static Object getFieldValueUsingGetter(Object bean, Field field) throws Exception {
// Assuming the getter method follows the Java Bean convention:
// getMethodName for fields or isMethodName for boolean fields
String getterMethodName = "get" + capitalize(field.getName());
if (field.getType().isAssignableFrom(boolean.class)) {
getterMethodName = "is" + capitalize(field.getName());
}
try {
// Attempt to call the getter method to get the field value
return bean.getClass().getMethod(getterMethodName).invoke(bean);
} catch (NoSuchMethodException e) {
// If no getter method found, return null. This might indicate
// a need for direct field access which should be avoided if possible.
return null;
}
}
private static String capitalize(String str) {
if (StringUtils.isEmpty(str)) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}

16
easyexcel-core/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java

@ -1,18 +1,11 @@
package com.alibaba.excel.write.executor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.metadata.FieldCache;
import com.alibaba.excel.metadata.FieldWrapper;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.support.cglib.beans.BeanMap;
import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.FieldUtils;
@ -25,11 +18,16 @@ import com.alibaba.excel.write.metadata.MapRowData;
import com.alibaba.excel.write.metadata.RowData;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Add the data into excel
*
@ -137,7 +135,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
private void addJavaObjectToExcel(Object oneRowData, Row row, int rowIndex, int relativeRowIndex) {
WriteHolder currentWriteHolder = writeContext.currentWriteHolder();
BeanMap beanMap = BeanMapUtils.create(oneRowData);
Map<String, Object> beanMap = BeanMapUtils.create(oneRowData);
// Bean the contains of the Map Key method with poor performance,So to create a keySet here
Set<String> beanKeySet = new HashSet<>(beanMap.keySet());
Set<String> beanMapHandledSet = new HashSet<>();

11
easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java

@ -1,17 +1,16 @@
package com.alibaba.easyexcel.test.temp;
import java.util.List;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.cglib.beans.BeanMap;
import com.alibaba.excel.support.cglib.core.DebuggingClassWriter;
import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.fastjson2.JSON;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
/**
* 临时测试
*
@ -33,14 +32,14 @@ public class Xls03Test {
public void test2() {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,
"/Users/zhuangjiaju/IdeaProjects/easyexcel/target");
"/Users/zhuangjiaju/IdeaProjects/easyexcel/target");
CamlData camlData = new CamlData();
//camlData.setTest("test2");
//camlData.setAEst("test3");
//camlData.setTEST("test4");
BeanMap beanMap = BeanMapUtils.create(camlData);
Map<String, Object> beanMap = BeanMapUtils.create(camlData);
LOGGER.info("test:{}", beanMap.get("test"));
LOGGER.info("test:{}", beanMap.get("Test"));

25
easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue3913/CsbDataItemTest.java

@ -0,0 +1,25 @@
package com.alibaba.easyexcel.test.temp.issue3913;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@EqualsAndHashCode
@ToString
public class CsbDataItemTest {
@ExcelProperty("业务对象")
private String field1 = "云订单";
@ExcelProperty("数据标准IT编码")
private String A;
@ExcelProperty("长度")
private Integer field3;
@ExcelProperty("精度")
private Integer D;
}

41
easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue3913/Issue3913Test.java

@ -0,0 +1,41 @@
package com.alibaba.easyexcel.test.temp.issue3913;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class Issue3913Test {
//Issue link: https://github.com/alibaba/easyexcel/issues/3913
@Test
public void IssueTest1() {
String fileName = "d:/out.xlsx";
// 这里 需要指定写用哪个class去写
try (com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(fileName, CsbDataItemTest.class).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet("output").build();
excelWriter.write(genData(), writeSheet);
}
log.info("write file success");
}
private List<CsbDataItemTest> genData() {
List<CsbDataItemTest> list = new ArrayList<>();
for (int i = 0; i < 2; i++) {
CsbDataItemTest item = new CsbDataItemTest();
item.setField1("云订单");
item.setA("comment");
item.setField3(i);
item.setD(i * 20);
list.add(item);
}
log.info("the size : {}", list.size());
return list;
}
}

16
easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java

@ -1,18 +1,11 @@
package com.alibaba.easyexcel.test.temp.write;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.easyexcel.test.demo.read.CustomStringStringConverter;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.cglib.beans.BeanMap;
import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.ListUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
@ -26,6 +19,11 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class TempWriteTest {
@ -51,7 +49,7 @@ public class TempWriteTest {
TempWriteData tempWriteData = new TempWriteData();
tempWriteData.setName("1");
tempWriteData.setName1("2");
BeanMap beanMap = BeanMapUtils.create(tempWriteData);
Map<String, Object> beanMap = BeanMapUtils.create(tempWriteData);
log.info("d1{}", beanMap.get("name"));
log.info("d2{}", beanMap.get("name1"));
@ -60,7 +58,7 @@ public class TempWriteTest {
Map<String, String> map = new HashMap<>();
map.put("name", "zs");
BeanMap beanMap2 = BeanMapUtils.create(tempWriteData2);
Map<String, Object> beanMap2 = BeanMapUtils.create(tempWriteData2);
beanMap2.putAll(map);
log.info("3{}", tempWriteData2.getName());

Loading…
Cancel
Save