Browse Source

* 提高xlsx读取兼容性:在存在第一行很多空列的情况下,忽略空列

pull/2880/head
Jiaju Zhuang 2 years ago
parent
commit
d04850c89e
  1. 2
      README.md
  2. 12
      easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
  3. 2
      easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java
  4. 13
      easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java
  5. 10
      easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java
  6. BIN
      easyexcel-test/src/test/resources/compatibility/t03.xlsx
  7. 2
      pom.xml
  8. 6
      update.md

2
README.md

@ -36,7 +36,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>3.1.3</version> <version>3.1.4</version>
</dependency> </dependency>
``` ```

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

@ -25,14 +25,6 @@ import org.springframework.cglib.beans.BeanMap;
*/ */
public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<Integer, ReadCellData<?>>> { public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<Integer, ReadCellData<?>>> {
@Override
public void invokeHead(Map<Integer, ReadCellData<?>> cellDataMap, AnalysisContext context) {
if (context.readSheetHolder().getMaxDataHeadSize() == null
|| context.readSheetHolder().getMaxDataHeadSize() < CollectionUtils.size(cellDataMap)) {
context.readSheetHolder().setMaxDataHeadSize(CollectionUtils.size(cellDataMap));
}
}
@Override @Override
public void invoke(Map<Integer, ReadCellData<?>> cellDataMap, AnalysisContext context) { public void invoke(Map<Integer, ReadCellData<?>> cellDataMap, AnalysisContext context) {
ReadSheetHolder readSheetHolder = context.readSheetHolder(); ReadSheetHolder readSheetHolder = context.readSheetHolder();
@ -73,8 +65,8 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<
if (readSheetHolder.excelReadHeadProperty().getHeadMap().size() > 0) { if (readSheetHolder.excelReadHeadProperty().getHeadMap().size() > 0) {
return readSheetHolder.excelReadHeadProperty().getHeadMap().size(); return readSheetHolder.excelReadHeadProperty().getHeadMap().size();
} }
if (readSheetHolder.getMaxDataHeadSize() != null) { if (readSheetHolder.getMaxNotEmptyDataHeadSize() != null) {
return readSheetHolder.getMaxDataHeadSize(); return readSheetHolder.getMaxNotEmptyDataHeadSize();
} }
return 0; return 0;
} }

2
easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java

@ -65,7 +65,7 @@ public class ReadSheetHolder extends AbstractReadHolder {
* Read the size of the largest head in sheet head data. * Read the size of the largest head in sheet head data.
* see https://github.com/alibaba/easyexcel/issues/2014 * see https://github.com/alibaba/easyexcel/issues/2014
*/ */
private Integer maxDataHeadSize; private Integer maxNotEmptyDataHeadSize;
public ReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { public ReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) {
super(readSheet, readWorkbookHolder); super(readSheet, readWorkbookHolder);

13
easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java

@ -3,8 +3,11 @@ package com.alibaba.excel.read.processor;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisException;
@ -17,6 +20,8 @@ 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.StringUtils; import com.alibaba.excel.util.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -111,6 +116,14 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor {
} }
private void buildHead(AnalysisContext analysisContext, Map<Integer, ReadCellData<?>> cellDataMap) { private void buildHead(AnalysisContext analysisContext, Map<Integer, ReadCellData<?>> cellDataMap) {
// Rule out empty head, and then take the largest column
if (MapUtils.isNotEmpty(cellDataMap)) {
cellDataMap.entrySet()
.stream()
.filter(entry -> CellDataTypeEnum.EMPTY != entry.getValue().getType())
.forEach(entry -> analysisContext.readSheetHolder().setMaxNotEmptyDataHeadSize(entry.getKey()));
}
if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) { if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) {
return; return;
} }

10
easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java

@ -42,4 +42,14 @@ public class CompatibilityTest {
Map<Integer, Object> row2 = list.get(2); Map<Integer, Object> row2 = list.get(2);
Assert.assertEquals("1,2-戊二醇", row2.get(2)); Assert.assertEquals("1,2-戊二醇", row2.get(2));
} }
@Test
public void t03() {
// Exist in `sharedStrings.xml` `x:t` start tag, need to be compatible
List<Map<Integer, Object>> list = EasyExcel.read(TestFileUtil.getPath() + "compatibility/t03.xlsx").sheet().doReadSync();
log.info("data:{}", JSON.toJSONString(list));
Assert.assertEquals(1, list.size());
Map<Integer, Object> row0 = list.get(0);
Assert.assertEquals(12, row0.size());
}
} }

BIN
easyexcel-test/src/test/resources/compatibility/t03.xlsx

Binary file not shown.

2
pom.xml

@ -20,7 +20,7 @@
<properties> <properties>
<revision>3.1.3</revision> <revision>3.1.4</revision>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.8</jdk.version> <jdk.version>1.8</jdk.version>
<gpg.skip>true</gpg.skip> <gpg.skip>true</gpg.skip>

6
update.md

@ -1,3 +1,7 @@
# 3.1.4
* 提高xlsx读取兼容性:在存在第一行很多空列的情况下,忽略空列
# 3.1.3 # 3.1.3
* 提高xlsx兼容性:兼容`sharedStrings.xml` 存在 `x:t`标签的情况 * 提高xlsx兼容性:兼容`sharedStrings.xml` 存在 `x:t`标签的情况
@ -156,7 +160,9 @@
* 发布正式版 * 发布正式版
* 修复第一行为空不会调用`invokeHeadMap`的bug [Issue #993](https://github.com/alibaba/easyexcel/issues/993) * 修复第一行为空不会调用`invokeHeadMap`的bug [Issue #993](https://github.com/alibaba/easyexcel/issues/993)
* *
当类的属性没有按照ExcelProperty的属性index顺序排序的时候,写数据出现错乱 [Issue #1046](https://github.com/alibaba/easyexcel/issues/1046) 当类的属性没有按照ExcelProperty的属性index顺序排序的时候,写数据出现错乱 [Issue #1046](https://github.com/alibaba/easyexcel/issues/1046)
* 新增支持自定义转换器 入参可以为空 实现`NullableObjectConverter` * 新增支持自定义转换器 入参可以为空 实现`NullableObjectConverter`
即可 [Issue #1084](https://github.com/alibaba/easyexcel/issues/1084) 即可 [Issue #1084](https://github.com/alibaba/easyexcel/issues/1084)
* 修复xls丢失结束标记的情况下 会漏读最后一行 * 修复xls丢失结束标记的情况下 会漏读最后一行

Loading…
Cancel
Save