bengbengbalabalabeng commented on issue #656:
URL: https://github.com/apache/fesod/issues/656#issuecomment-3436612727
可以通过 `@ExcelProperty` 注解中指定 `index` 属性来临时规避问题。下面是一个示例代码,供参考:
```java
@EqualsAndHashCode(callSuper = false)
@Data
public class MultiHeadIndexBindingData implements Serializable {
@ExcelProperty(index = 0)
private Integer no;
@ExcelProperty(index = 1)
private String name;
@ExcelProperty(index = 2, converter = StringBooleanConverter.class)
private Boolean isCurrVillage;
@ExcelProperty(index = 3)
private String aframework;
@ExcelProperty(index = 4)
private String abrickConcrete;
@ExcelProperty(index = 5)
private String abrickWood;
@ExcelProperty(index = 6)
private String awood;
@ExcelProperty(index = 7)
private String aother;
@ExcelProperty(index = 8)
private String bframework;
@ExcelProperty(index = 9)
private String bbrickConcrete;
@ExcelProperty(index = 10)
private String bbrickWood;
@ExcelProperty(index = 11)
private String bwood;
@ExcelProperty(index = 12)
private String bother;
}
```
```java
@Slf4j
public class MultiHeadBindingTest {
@Test
void testMultiHeadReadWithIndexBinding() {
String path = TestFileUtil.getPath() + "demo" + File.separator +
"multi-head-binding-test.xlsx";
List<MultiHeadIndexBindingData> rows = FastExcel.read()
.file(path)
.head(MultiHeadIndexBindingData.class)
.headRowNumber(3)
.sheet()
.doReadSync();
log.info("\nrows\n: {}", JSON.toPrettyJSONString(rows));
}
}
```
示例 Excel (AI Mock):
<img width="996" height="441" alt="Image"
src="https://github.com/user-attachments/assets/58f8c29a-c382-421c-8ae0-29d85fb2d77d"
/>
输出结果:
```text
[{
"no": 1,
"name": "客厅装修",
"isCurrVillage": true,
"aframework": "12",
"abrickConcrete": "0",
"abrickWood": "0",
"awood": "1",
"aother": "5",
"bframework": "2",
"bbrickConcrete": "0",
"bbrickWood": "0",
"bwood": "0",
"bother": "0"
}, ......]
```
---
问题代码复现:
```java
@EqualsAndHashCode(callSuper = false)
@Data
public class MultiHeadValueBindingData implements Serializable {
// 或者 @ExcelProperty(value = {"序号"})
@ExcelProperty(value = {"序号", "序号", "序号"})
private Integer no;
// 或者 @ExcelProperty(value = {"项目名称"})
@ExcelProperty(value = {"项目名称", "项目名称", "项目名称"})
private String name;
// 或者 @ExcelProperty(value = {"是否本村"}, converter =
StringBooleanConverter.class)
@ExcelProperty(value = {"是否本村", "是否本村", "是否本村"}, converter =
StringBooleanConverter.class)
private Boolean isCurrVillage;
@ExcelProperty(value = {"xxxx", "结构", "框架"})
private String aframework;
@ExcelProperty(value = {"xxxx", "结构", "砖混"})
private String abrickConcrete;
@ExcelProperty(value = {"xxxx", "结构", "砖木"})
private String abrickWood;
@ExcelProperty(value = {"xxxx", "结构", "木"})
private String awood;
@ExcelProperty(value = {"xxxx", "结构", "其它"})
private String aother;
@ExcelProperty(value = {"xxxx", "实际用于经营", "框架"})
private String bframework;
@ExcelProperty(value = {"xxxx", "实际用于经营", "砖混"})
private String bbrickConcrete;
@ExcelProperty(value = {"xxxx", "实际用于经营", "砖木"})
private String bbrickWood;
@ExcelProperty(value = {"xxxx", "实际用于经营", "木"})
private String bwood;
@ExcelProperty(value = {"xxxx", "实际用于经营", "其它"})
private String bother;
}
```
```java
@Slf4j
public class MultiHeadBindingTest {
@Test
void testMultiHeadReadWithIndexBinding() {
String path = TestFileUtil.getPath() + "demo" + File.separator +
"multi-head-binding-test.xlsx";
List<MultiHeadValueBindingData> rows = FastExcel.read()
.file(path)
.head(MultiHeadValueBindingData.class)
.headRowNumber(3)
.sheet()
.doReadSync();
log.info("\nrows\n: {}", JSON.toPrettyJSONString(rows));
}
}
```
输出结果:
```text
[{
"no": null,
"name": null,
"isCurrVillage": null,
"aframework": null,
"abrickConcrete": null,
"abrickWood": null,
"awood": null,
"aother": null,
"bframework": "12",
"bbrickConcrete": "0",
"bbrickWood": "0",
"bwood": "1",
"bother": "5"
}, ......]
```
初步分析:
`headNameList.get(headNameList.size() - 1)` 获取 headName 存在缺陷
1. 可能获取不到合并单元格的 headName 值(IS NULL)
2. headName 存在重复时,`tmpHeadMap.put(...)` 的逻辑会覆盖已存在的值
Head 绑定异常定位:
`cn.idev.excel.read.processor.DefaultAnalysisEventProcessor#buildHead`
```java
private void buildHead(AnalysisContext analysisContext, Map<Integer,
ReadCellData<?>> cellDataMap) {
// 省略......
Map<Integer, String> dataMap =
ConverterUtils.convertToStringMap(cellDataMap, analysisContext);
ExcelReadHeadProperty excelHeadPropertyData =
analysisContext.readSheetHolder().excelReadHeadProperty();
Map<Integer, Head> headMapData = excelHeadPropertyData.getHeadMap();
Map<Integer, Head> tmpHeadMap = new HashMap<Integer,
Head>(headMapData.size() * 4 / 3 + 1);
for (Map.Entry<Integer, Head> entry : headMapData.entrySet()) {
Head headData = entry.getValue();
// 存在 index 定义时直接 put 正常 continue
if (headData.getForceIndex() || !headData.getForceName()) {
tmpHeadMap.put(entry.getKey(), headData);
continue;
}
List<String> headNameList = headData.getHeadNameList();
// 1. 问题: headName IS NULL
String headName = headNameList.get(headNameList.size() - 1);
for (Map.Entry<Integer, String> stringEntry :
dataMap.entrySet()) {
if (stringEntry == null) {
continue;
}
String headString = stringEntry.getValue();
Integer stringKey = stringEntry.getKey();
if (StringUtils.isEmpty(headString)) {
continue;
}
if
(analysisContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
headString = headString.trim();
}
if (headName.equals(headString)) {
headData.setColumnIndex(stringKey);
// 2. 问题: 重复赋值
tmpHeadMap.put(stringKey, headData);
break;
}
}
}
excelHeadPropertyData.setHeadMap(tmpHeadMap);
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]