Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.alibaba.excel.exception;


import com.sun.istack.internal.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
* Data convert group exception
*
* @author Jasonyou
* @date 2024/03/24
*/
@Getter
@Setter
@EqualsAndHashCode
public class ExcelDataConvertGroupException extends ExcelRuntimeException{
private Integer rowIndex;
private List<ExcelDataConvertException> group;
public ExcelDataConvertGroupException(){
this(null,null,null,null);
}
public ExcelDataConvertGroupException(Integer rowIndex){
this(rowIndex,null,null,null);
}
public ExcelDataConvertGroupException(Integer rowIndex,List<ExcelDataConvertException> group){
this(rowIndex,group,null,null);
}
public ExcelDataConvertGroupException(Integer rowIndex,List<ExcelDataConvertException> group,String message){
this(rowIndex,group,message,null);
}
public ExcelDataConvertGroupException(Integer rowIndex, List<ExcelDataConvertException> group,String message,Throwable cause){
super(message,cause);
this.rowIndex=rowIndex;
if(group==null) {
this.group = new ArrayList<>();
}
}

@Override
public String getMessage() {
return Optional.ofNullable(super.getMessage()).orElse("") +"all exceptions:\n"+group.stream().map(ExcelDataConvertException::getMessage).collect(Collectors.toList()).toString();
}

public boolean addException(ExcelDataConvertException exception){
return group.add(exception);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.enums.ReadDefaultReturnEnum;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.exception.ExcelDataConvertGroupException;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.metadata.data.ReadCellData;
Expand All @@ -25,6 +26,7 @@
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.util.StringUtils;

import org.apache.commons.math3.exception.util.ExceptionContext;
import org.springframework.cglib.beans.BeanMap;

/**
Expand All @@ -49,6 +51,8 @@ private Object buildNoModel(Map<Integer, ReadCellData<?>> cellDataMap, ReadSheet
AnalysisContext context) {
int index = 0;
Map<Integer, Object> map = MapUtils.newLinkedHashMapWithExpectedSize(cellDataMap.size());
Integer rowIndex = context.readRowHolder().getRowIndex();
ExcelDataConvertGroupException groupException = new ExcelDataConvertGroupException(rowIndex);
for (Map.Entry<Integer, ReadCellData<?>> entry : cellDataMap.entrySet()) {
Integer key = entry.getKey();
ReadCellData<?> cellData = entry.getValue();
Expand All @@ -60,10 +64,14 @@ private Object buildNoModel(Map<Integer, ReadCellData<?>> cellDataMap, ReadSheet

ReadDefaultReturnEnum readDefaultReturn = context.readWorkbookHolder().getReadDefaultReturn();
if (readDefaultReturn == ReadDefaultReturnEnum.STRING) {
// string
map.put(key,
(String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(),
context, context.readRowHolder().getRowIndex(), key));
try {
// string
map.put(key,
(String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(),
context, context.readRowHolder().getRowIndex(), key));
} catch (ExcelDataConvertException e) {
groupException.addException(e);
}
} else {
// retrun ReadCellData
ReadCellData<?> convertedReadCellData = convertReadCellData(cellData,
Expand All @@ -75,6 +83,9 @@ private Object buildNoModel(Map<Integer, ReadCellData<?>> cellDataMap, ReadSheet
}
}
}
if(!groupException.getGroup().isEmpty()){
throw groupException;
}
// fix https://github.com/alibaba/easyexcel/issues/2014
int headSize = calculateHeadSize(readSheetHolder);
while (index < headSize) {
Expand Down Expand Up @@ -139,22 +150,32 @@ private Object buildUserModel(Map<Integer, ReadCellData<?>> cellDataMap, ReadShe
}
Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap();
BeanMap dataMap = BeanMapUtils.create(resultModel);
Integer rowIndex = context.readRowHolder().getRowIndex();
ExcelDataConvertGroupException groupException = new ExcelDataConvertGroupException(rowIndex );
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Integer index = entry.getKey();
Head head = entry.getValue();
String fieldName = head.getFieldName();
if (!cellDataMap.containsKey(index)) {
continue;
}
ReadCellData<?> cellData = cellDataMap.get(index);
Object value = ConverterUtils.convertToJavaObject(cellData, head.getField(),
ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(),
fieldName, readSheetHolder), readSheetHolder.converterMap(), context,
context.readRowHolder().getRowIndex(), index);
if (value != null) {
dataMap.put(fieldName, value);

try {
ReadCellData<?> cellData = cellDataMap.get(index);
Object value = ConverterUtils.convertToJavaObject(cellData, head.getField(),
ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(),
fieldName, readSheetHolder), readSheetHolder.converterMap(), context,
context.readRowHolder().getRowIndex(), index);
if (value != null) {
dataMap.put(fieldName, value);
}
}catch (ExcelDataConvertException e){
groupException.addException(e);
}
}
if(!groupException.getGroup().isEmpty()){
throw groupException;
}
return resultModel;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.alibaba.easyexcel.test.core.model;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

import java.util.Date;

@Getter
@Setter
@EqualsAndHashCode
public class DemoData {
@ExcelProperty("字符串")
private String string;
@ExcelProperty("浮点数")
private Double doubleData;
@ExcelProperty("日期")
private Date date;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.alibaba.easyexcel.test.core.model;

import com.alibaba.excel.annotation.ExcelProperty;

import java.util.Date;

/**
* @author Jasonyou
* @date 2024/03/24
*/
public class DemoDataConvertErro {
//exchange the type of the following fields in order to produce type conversion errors
@ExcelProperty(index =0)
private DemoData string;
@ExcelProperty(index = 1)
private DemoData doubleData;
@ExcelProperty(index = 2)
private DemoData date;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package com.alibaba.easyexcel.test.core.model;

import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.enums.ReadDefaultReturnEnum;
import com.alibaba.excel.exception.ExcelDataConvertGroupException;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
* @author Jasonyou
* @date 2024/03/24
*/
@Slf4j
public class ModelBuildEventListenerTest {

private static File file07;
private static File file03;
private static File fileCsv;
private static File fileRepeat07;
private static File fileRepeat03;
private static File fileRepeatCsv;
private static LocalDateTime localDateTime;
private static String dateTimeStr;
@BeforeAll
public static void init() {
file07 = TestFileUtil.createNewFile("Model07.xlsx");
file03 = TestFileUtil.createNewFile("Model03.xls");
fileCsv = TestFileUtil.createNewFile("ModelCsv.csv");
fileRepeat07 = TestFileUtil.createNewFile("ModelRepeat07.xlsx");
fileRepeat03 = TestFileUtil.createNewFile("ModelRepeat03.xls");
fileRepeatCsv = TestFileUtil.createNewFile("ModelRepeatCsv.csv");
dateTimeStr="2020-01-01 01:01:01";
}

@Test
public void t01ReadAndWrite07WithModel() throws Exception {
readAndWrite(file07, fileRepeat07, false);
}
@Test
public void t02ReadAndWrite03() throws Exception {
readAndWrite(file03, fileRepeat03, false);
}

@Test
public void t03ReadAndWriteCsv() throws Exception {
readAndWrite(fileCsv, fileRepeatCsv, true);
}

@Test void testConvertGroup()throws Exception{
Assertions.assertThrows(ExcelDataConvertGroupException.class, ()->{
try {
EasyExcel.write(file07, DemoData.class).sheet().doWrite(data());
EasyExcel.read(file07).head(DemoDataConvertErro.class).sheet().doReadSync();

} catch (ExcelDataConvertGroupException e) {
log.info("testConvertGroup:{}",e.getMessage());
throw e;
}
});
}

private void readAndWrite(File file, File fileRepeat, boolean isCsv) throws Exception {
EasyExcel.write(file, DemoData.class).sheet().doWrite(data());
List<DemoData> result = EasyExcel.read(file).head(DemoData.class).sheet().doReadSync();
Assertions.assertEquals(10, result.size());
DemoData data10 = result.get(9);
Assertions.assertEquals("string19", data10.getString());
Assertions.assertEquals(109, data10.getDoubleData());
Assertions.assertEquals(DateUtils.parseDate(dateTimeStr),data10.getDate());

List<Map<Integer, Object>> actualDataList = EasyExcel.read(file)
.readDefaultReturn(ReadDefaultReturnEnum.ACTUAL_DATA)
.sheet()
.doReadSync();

log.info("actualDataList:{}", JSON.toJSONString(actualDataList, JSONWriter.Feature.PrettyFormat) );
Assertions.assertEquals(10, actualDataList.size());
Map<Integer, Object> actualData10 = actualDataList.get(9);
Assertions.assertEquals("string19", actualData10.get(0));
if (isCsv) {
// CSV only string type
Assertions.assertEquals("109.0", actualData10.get(1));
Assertions.assertEquals(dateTimeStr, actualData10.get(2));
} else {
Assertions.assertEquals(0, new BigDecimal("109").compareTo((BigDecimal)actualData10.get(1)));
Assertions.assertEquals(LocalDateTime.of(2020, 1, 1, 1, 1, 1), actualData10.get(2));
}

List<Map<Integer, ReadCellData<?>>> readCellDataList = EasyExcel.read(file)
.readDefaultReturn(ReadDefaultReturnEnum.READ_CELL_DATA)
.sheet()
.doReadSync();
log.info("readCellDataList:{}", JSON.toJSONString(readCellDataList, JSONWriter.Feature.PrettyFormat));
Assertions.assertEquals(10, readCellDataList.size());
Map<Integer, ReadCellData<?>> readCellData10 = readCellDataList.get(9);
Assertions.assertEquals("string19", readCellData10.get(0).getData());
if (isCsv) {
// CSV only string type
Assertions.assertEquals("109.0", readCellData10.get(1).getData());
Assertions.assertEquals(dateTimeStr, readCellData10.get(2).getData());
} else {
Assertions.assertEquals(0, new BigDecimal("109").compareTo((BigDecimal)readCellData10.get(1).getData()));
Assertions.assertEquals(LocalDateTime.of(2020, 1, 1, 1, 1, 1), readCellData10.get(2).getData());
}

EasyExcel.write(fileRepeat, DemoData.class).sheet().doWrite(result);
result = EasyExcel.read(fileRepeat).head(DemoData.class).sheet().doReadSync();
Assertions.assertEquals(10, result.size());
data10 = result.get(9);
Assertions.assertEquals("string19", data10.getString());
Assertions.assertEquals(109, data10.getDoubleData());
Assertions.assertEquals(DateUtils.parseDate(dateTimeStr),data10.getDate());
}

private List<DemoData> data() throws Exception {
List<DemoData> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
DemoData demoData = new DemoData();
demoData.setString("string1"+i);
demoData.setDoubleData((double) (100+i));
demoData.setDate(DateUtils.parseDate(dateTimeStr));
list.add(demoData);
}
return list;
}
}
Binary file added easyexcel-test/src/test/resources/modle/demo.xlsx
Binary file not shown.