Browse Source

* 修复根据文件流解析 CSV 文件类型错误的问题 [Issue #2236](https://github.com/alibaba/easyexcel/issues/2236)

pull/2598/head
zhengzhicong 3 years ago
parent
commit
85dc43c995
  1. 4
      easyexcel-core/src/main/java/com/alibaba/excel/ExcelReader.java
  2. 2
      easyexcel-core/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  3. 40
      easyexcel-core/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java
  4. 41
      easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java
  5. 2
      easyexcel-test/src/test/resources/fill/simple.csv
  6. 2
      easyexcel-test/src/test/resources/simple/simpleCsv.csv
  7. BIN
      easyexcel-test/src/test/resources/simple/simpleCsvRenameByXls.csv
  8. BIN
      easyexcel-test/src/test/resources/simple/simpleCsvRenameByXlsx.csv

4
easyexcel-core/src/main/java/com/alibaba/excel/ExcelReader.java

@ -95,9 +95,7 @@ public class ExcelReader implements Closeable {
* Complete the entire read file.Release the cache and close stream. * Complete the entire read file.Release the cache and close stream.
*/ */
public void finish() { public void finish() {
if (excelAnalyser != null) { excelAnalyser.finish();
excelAnalyser.finish();
}
} }
@Override @Override

2
easyexcel-core/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java

@ -136,7 +136,7 @@ public class ExcelHeadProperty {
*/ */
private void initOneColumnProperty(int index, Field field, Boolean forceIndex) { private void initOneColumnProperty(int index, Field field, Boolean forceIndex) {
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
List<String> tmpHeadList = new ArrayList<String>(); List<String> tmpHeadList = new ArrayList<>();
String fieldName = FieldUtils.resolveCglibFieldName(field); String fieldName = FieldUtils.resolveCglibFieldName(field);
boolean notForceName = excelProperty == null || excelProperty.value().length <= 0 boolean notForceName = excelProperty == null || excelProperty.value().length <= 0
|| (excelProperty.value().length == 1 && StringUtils.isEmpty((excelProperty.value())[0])); || (excelProperty.value().length == 1 && StringUtils.isEmpty((excelProperty.value())[0]));

40
easyexcel-core/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java

@ -1,18 +1,17 @@
package com.alibaba.excel.support; package com.alibaba.excel.support;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import lombok.Getter; import lombok.Getter;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
/** /**
* @author jipengfei * @author jipengfei
*/ */
@ -22,15 +21,15 @@ public enum ExcelTypeEnum {
/** /**
* csv * csv
*/ */
CSV(".csv", new byte[] {-27, -89, -109, -27}), CSV(".csv", new byte[]{-27, -89, -109, -27}),
/** /**
* xls * xls
*/ */
XLS(".xls", new byte[] {-48, -49, 17, -32, -95, -79, 26, -31}), XLS(".xls", new byte[]{-48, -49, 17, -32, -95, -79, 26, -31}),
/** /**
* xlsx * xlsx
*/ */
XLSX(".xlsx", new byte[] {80, 75, 3, 4}); XLSX(".xlsx", new byte[]{80, 75, 3, 4});
final String value; final String value;
final byte[] magic; final byte[] magic;
@ -59,7 +58,7 @@ public enum ExcelTypeEnum {
} }
// If there is a password, use the FileMagic first // If there is a password, use the FileMagic first
if (!StringUtils.isEmpty(readWorkbook.getPassword())) { if (!StringUtils.isEmpty(readWorkbook.getPassword())) {
try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file))) { try (BufferedInputStream bufferedInputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
return recognitionExcelType(bufferedInputStream); return recognitionExcelType(bufferedInputStream);
} }
} }
@ -73,7 +72,7 @@ public enum ExcelTypeEnum {
return CSV; return CSV;
} }
if (StringUtils.isEmpty(readWorkbook.getPassword())) { if (StringUtils.isEmpty(readWorkbook.getPassword())) {
try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file))) { try (BufferedInputStream bufferedInputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
return recognitionExcelType(bufferedInputStream); return recognitionExcelType(bufferedInputStream);
} }
} }
@ -94,11 +93,13 @@ public enum ExcelTypeEnum {
private static ExcelTypeEnum recognitionExcelType(InputStream inputStream) throws Exception { private static ExcelTypeEnum recognitionExcelType(InputStream inputStream) throws Exception {
// Grab the first bytes of this stream // Grab the first bytes of this stream
byte[] data = IOUtils.peekFirstNBytes(inputStream, MAX_PATTERN_LENGTH); byte[] data = IOUtils.peekFirstNBytes(inputStream, MAX_PATTERN_LENGTH);
if (findMagic(XLSX.magic, data)) { if (findMagic(XLSX.getMagic(), data)) {
return XLSX; return XLSX;
} else if (findMagic(CSV.magic, data)) { }
if (findMagic(CSV.magic, data)) {
return CSV; return CSV;
} else if (findMagic(XLS.magic, data)) { }
if (findMagic(XLS.magic, data)) {
return XLS; return XLS;
} }
throw new ExcelCommonException( throw new ExcelCommonException(
@ -107,12 +108,15 @@ public enum ExcelTypeEnum {
private static boolean findMagic(byte[] expected, byte[] actual) { private static boolean findMagic(byte[] expected, byte[] actual) {
int i = 0; int i = 0;
for (byte expectedByte : expected) { for (byte actualByte : actual) {
if (actual[i++] != expectedByte && expectedByte != '?') { if (actualByte == expected[i]) {
return false; i++;
}
if (i == expected.length - 1) {
return true;
} }
} }
return true; return false;
} }
} }

41
easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java

@ -1,21 +1,22 @@
package com.alibaba.easyexcel.test.core.simple; package com.alibaba.easyexcel.test.core.simple;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import org.junit.Assert; import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
import org.junit.runners.MethodSorters; import org.junit.runners.MethodSorters;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@ -33,6 +34,30 @@ public class SimpleDataTest {
fileCsv = TestFileUtil.createNewFile("simpleCsv.csv"); fileCsv = TestFileUtil.createNewFile("simpleCsv.csv");
} }
@Test
public void simpleCsvByWrite() throws IOException {
File csvFile = TestFileUtil.readFile("simple" + File.separator + "simpleCsv.csv");
EasyExcel.read(Files.newInputStream(csvFile.toPath()), SimpleData.class,
new SimpleDataSheetNameListener()).sheet("simple").doRead();
}
@Test
public void simpleCsvRenameByXlsx() throws IOException {
File csvFile = TestFileUtil.readFile("simple" + File.separator + "simpleCsvRenameByXlsx.csv");
EasyExcel.read(Files.newInputStream(csvFile.toPath()), SimpleData.class,
new SimpleDataSheetNameListener()).sheet("simple").doRead();
}
@Test
public void simpleCsvRenameByXls() throws IOException {
File csvFile = TestFileUtil.readFile("simple" + File.separator + "simpleCsvRenameByXls.csv");
EasyExcel.read(Files.newInputStream(csvFile.toPath()), SimpleData.class,
new SimpleDataSheetNameListener()).sheet("simple").doRead();
}
@Test @Test
public void t01ReadAndWrite07() { public void t01ReadAndWrite07() {
readAndWrite(file07); readAndWrite(file07);
@ -99,7 +124,7 @@ public class SimpleDataTest {
List<Object> list = EasyExcel.read(file).head(SimpleData.class).sheet().doReadSync(); List<Object> list = EasyExcel.read(file).head(SimpleData.class).sheet().doReadSync();
Assert.assertEquals(list.size(), 10); Assert.assertEquals(list.size(), 10);
Assert.assertTrue(list.get(0) instanceof SimpleData); Assert.assertTrue(list.get(0) instanceof SimpleData);
Assert.assertEquals(((SimpleData)list.get(0)).getName(), "姓名0"); Assert.assertEquals(((SimpleData) list.get(0)).getName(), "姓名0");
} }
private List<SimpleData> data() { private List<SimpleData> data() {

2
easyexcel-test/src/test/resources/fill/simple.csv

@ -1,2 +0,0 @@
姓名,数字,复杂,忽略,空
{name},{number},{name}今年{number}岁了,\{name\}忽略,{name},空{.empty}
1 姓名 数字 复杂 忽略
2 {name} {number} {name}今年{number}岁了 \{name\}忽略,{name} 空{.empty}

2
easyexcel-test/src/test/resources/simple/simpleCsv.csv

@ -0,0 +1,2 @@
姓名
200025772
1 姓名
2 200025772

BIN
easyexcel-test/src/test/resources/simple/simpleCsvRenameByXls.csv

Binary file not shown.
Can't render this file because it contains an unexpected character in line 1 and column 1213.

BIN
easyexcel-test/src/test/resources/simple/simpleCsvRenameByXlsx.csv

Binary file not shown.
Can't render this file because it contains an unexpected character in line 2 and column 475.
Loading…
Cancel
Save