diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java index fab5a7c6e..f5d6a4116 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java +++ b/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.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 @@ private Object buildUserModel(Map> cellDataMap, ReadShe "Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e); } Map headMap = excelReadHeadProperty.getHeadMap(); - BeanMap dataMap = BeanMapUtils.create(resultModel); + Map dataMap = BeanMapUtils.create(resultModel); for (Map.Entry entry : headMap.entrySet()) { Integer index = entry.getKey(); Head head = entry.getValue(); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/BeanMapUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/BeanMapUtils.java index 29926aa09..b7de4e13d 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/BeanMapUtils.java +++ b/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 @@ public class BeanMapUtils { /** - * Helper method to create a new BeanMap. For finer + * Helper method to create a new BeanMap. For finer * control over the generated instance, use a new instance of * BeanMap.Generator 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 BeanMap 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 create(Object bean) { + // Create a map to store the bean's property names and their corresponding values + Map propertyMap = new HashMap<>(16); + + // 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); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java b/easyexcel-core/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java index d1d82cc2e..a40387733 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java +++ b/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.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 @@ private void doAddBasicTypeToExcel(RowData oneRowData, Head head, Row row, int r private void addJavaObjectToExcel(Object oneRowData, Row row, int rowIndex, int relativeRowIndex) { WriteHolder currentWriteHolder = writeContext.currentWriteHolder(); - BeanMap beanMap = BeanMapUtils.create(oneRowData); + Map beanMap = BeanMapUtils.create(oneRowData); // Bean the contains of the Map Key method with poor performance,So to create a keySet here Set beanKeySet = new HashSet<>(beanMap.keySet()); Set beanMapHandledSet = new HashSet<>(); diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java index a43525ae3..238059c6c 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java +++ b/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 void test() { 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 beanMap = BeanMapUtils.create(camlData); LOGGER.info("test:{}", beanMap.get("test")); LOGGER.info("test:{}", beanMap.get("Test")); diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue3913/CsbDataItemTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue3913/CsbDataItemTest.java new file mode 100644 index 000000000..a7e1fa65c --- /dev/null +++ b/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; + + +} diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue3913/Issue3913Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue3913/Issue3913Test.java new file mode 100644 index 000000000..02b1892aa --- /dev/null +++ b/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 genData() { + List 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; + } + + +} diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java index 9f66a5076..51e1e1314 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java +++ b/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.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 void cglib() { TempWriteData tempWriteData = new TempWriteData(); tempWriteData.setName("1"); tempWriteData.setName1("2"); - BeanMap beanMap = BeanMapUtils.create(tempWriteData); + Map beanMap = BeanMapUtils.create(tempWriteData); log.info("d1{}", beanMap.get("name")); log.info("d2{}", beanMap.get("name1")); @@ -60,7 +58,7 @@ public void cglib() { Map map = new HashMap<>(); map.put("name", "zs"); - BeanMap beanMap2 = BeanMapUtils.create(tempWriteData2); + Map beanMap2 = BeanMapUtils.create(tempWriteData2); beanMap2.putAll(map); log.info("3{}", tempWriteData2.getName());