From 26c6de095b892fdbc2b804a30c0a95be41728b7a Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Mon, 16 Mar 2020 22:39:31 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99=E4=B8=BB=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=EF=BC=8C=E4=BB=A3=E7=A0=81=E6=9B=B4=E5=8A=A0=E4=BC=98=E9=9B=85?= =?UTF-8?q?=20=E6=B5=8B=E8=AF=95=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analysis/v07/handlers/CellTagHandler.java | 22 +++++++++++------ .../excel/constant/BuiltinFormats.java | 8 +++--- .../alibaba/excel/support/ExcelTypeEnum.java | 23 ++++++++++++++---- .../core/converter/ConverterDataListener.java | 2 +- .../ReadAllConverterDataListener.java | 2 +- .../test/core/dataformat/DateFormatTest.java | 2 -- .../test/core/encrypt/EncryptDataTest.java | 12 +++------ .../easyexcel/test/temp/read/CommentTest.java | 2 +- src/test/resources/dataformat/dataformat.xls | Bin 26112 -> 26112 bytes src/test/resources/dataformat/dataformat.xlsx | Bin 11754 -> 11746 bytes 10 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java index 7ba521da..2f354352 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -10,6 +10,7 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; import com.alibaba.excel.util.PositionUtils; +import com.alibaba.excel.util.StringUtils; /** * Cell Handler @@ -18,6 +19,8 @@ import com.alibaba.excel.util.PositionUtils; */ public class CellTagHandler extends AbstractXlsxTagHandler { + private static final int DEFAULT_FORMAT_INDEX = 0; + @Override public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); @@ -36,15 +39,18 @@ public class CellTagHandler extends AbstractXlsxTagHandler { // Put in data transformation information String dateFormatIndex = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_S); - if (dateFormatIndex != null) { - int dateFormatIndexInteger = Integer.parseInt(dateFormatIndex); - XSSFCellStyle xssfCellStyle = - xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable().getStyleAt(dateFormatIndexInteger); - int dataFormat = xssfCellStyle.getDataFormat(); - xlsxReadSheetHolder.getTempCellData().setDataFormat(dataFormat); - xlsxReadSheetHolder.getTempCellData().setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, - xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); + Integer dateFormatIndexInteger; + if (StringUtils.isEmpty(dateFormatIndex)) { + dateFormatIndexInteger = DEFAULT_FORMAT_INDEX; + } else { + dateFormatIndexInteger = Integer.parseInt(dateFormatIndex); } + XSSFCellStyle xssfCellStyle = + xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable().getStyleAt(dateFormatIndexInteger); + int dataFormat = xssfCellStyle.getDataFormat(); + xlsxReadSheetHolder.getTempCellData().setDataFormat(dataFormat); + xlsxReadSheetHolder.getTempCellData().setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, + xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); } } diff --git a/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java b/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java index 1dec2c68..95eb0b8f 100644 --- a/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java +++ b/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java @@ -64,8 +64,8 @@ public class BuiltinFormats { // 21 "h:mm:ss", // 22 - // The official documentation shows "m/d/yy h:mm", but the actual test is "yyyy/m/d h:mm". - "yyyy/m/d h:mm", + // The official documentation shows "m/d/yy h:mm", but the actual test is "yyyy-m-d h:mm". + "yyyy-m-d h:mm", // 23-26 No specific correspondence found in the official documentation. // 23 null, @@ -236,8 +236,8 @@ public class BuiltinFormats { // 21 "h:mm:ss", // 22 - // The official documentation shows "m/d/yy h:mm", but the actual test is "yyyy/m/d h:mm". - "yyyy/m/d h:mm", + // The official documentation shows "m/d/yy h:mm", but the actual test is "yyyy-m-d h:mm". + "yyyy-m-d h:mm", // 23-26 No specific correspondence found in the official documentation. // 23 null, diff --git a/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java b/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java index 100775d1..cdca07fd 100644 --- a/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java +++ b/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java @@ -10,6 +10,7 @@ import org.apache.poi.poifs.filesystem.FileMagic; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.read.metadata.ReadWorkbook; +import com.alibaba.excel.util.StringUtils; /** * @author jipengfei @@ -45,17 +46,29 @@ public enum ExcelTypeEnum { if (!file.exists()) { throw new ExcelAnalysisException("File " + file.getAbsolutePath() + " not exists."); } + // If there is a password, use the FileMagic first + if (!StringUtils.isEmpty(readWorkbook.getPassword())) { + BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); + try { + return recognitionExcelType(bufferedInputStream); + } finally { + bufferedInputStream.close(); + } + } + // Use the name to determine the type String fileName = file.getName(); if (fileName.endsWith(XLSX.getValue())) { return XLSX; } else if (fileName.endsWith(XLS.getValue())) { return XLS; } - BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); - try { - return recognitionExcelType(bufferedInputStream); - } finally { - bufferedInputStream.close(); + if (StringUtils.isEmpty(readWorkbook.getPassword())) { + BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); + try { + return recognitionExcelType(bufferedInputStream); + } finally { + bufferedInputStream.close(); + } } } if (!inputStream.markSupported()) { diff --git a/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java index abd5e1c3..210ca142 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java @@ -32,7 +32,7 @@ public class ConverterDataListener extends AnalysisEventListener Assert.assertEquals(list.size(), 1); ConverterData data = list.get(0); try { - Assert.assertEquals(data.getDate(), DateUtils.parseDate("2020-01-01 01:01:01")); + Assert.assertEquals(DateUtils.parseDate("2020-01-01 01:01:01"), data.getDate()); } catch (ParseException e) { throw new ExcelCommonException("Test Exception", e); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java index c8b5d8bf..d5da81ad 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java @@ -64,7 +64,7 @@ public class ReadAllConverterDataListener extends AnalysisEventListener list = EasyExcel.read(file, DateFormatData.class, null).locale(Locale.CHINA).sheet().doReadSync(); - System.out.println(JSON.toJSONString(list)); for (DateFormatData data : list) { Assert.assertEquals(data.getDateStringCn(), data.getDate()); Assert.assertEquals(data.getNumberStringCn(), data.getNumber()); diff --git a/src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataTest.java index 98f580f8..375f9bea 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataTest.java @@ -6,19 +6,15 @@ import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; -import org.junit.Assert; import org.junit.BeforeClass; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; import com.alibaba.easyexcel.test.core.simple.SimpleData; -import com.alibaba.easyexcel.test.core.simple.SimpleDataListener; -import com.alibaba.easyexcel.test.core.simple.SimpleDataSheetNameListener; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.excel.util.FileUtils; /** * @@ -51,12 +47,12 @@ public class EncryptDataTest { } @Test - public void t01ReadAndWriteStream07() throws Exception { + public void t03ReadAndWriteStream07() throws Exception { readAndWriteStream(file07OutputStream, ExcelTypeEnum.XLSX); } @Test - public void t02ReadAndWriteStream03() throws Exception { + public void t04ReadAndWriteStream03() throws Exception { readAndWriteStream(file03OutputStream, ExcelTypeEnum.XLS); } @@ -72,8 +68,8 @@ public class EncryptDataTest { fileOutputStream.close(); FileInputStream fileInputStream = new FileInputStream(file); - EasyExcel.read(fileInputStream, EncryptData.class, new EncryptDataListener()).password("123456") - .excelType(excelType).sheet().doRead(); + EasyExcel.read(fileInputStream, EncryptData.class, new EncryptDataListener()).password("123456").sheet() + .doRead(); } private List data() { diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java index 2c9235a7..22de3956 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java @@ -24,7 +24,7 @@ public class CommentTest { @Test public void comment() throws Exception { - File file = new File("D:\\test\\listHead07.xlsx"); + File file = new File("D:\\test\\d1.xlsx"); List> datas = EasyExcel.read(file).doReadAllSync(); for (Map data : datas) { LOGGER.info("数据:{}", JSON.toJSONString(data)); diff --git a/src/test/resources/dataformat/dataformat.xls b/src/test/resources/dataformat/dataformat.xls index c03847e4e5cde9f156ddf23b5d8263dc1357453e..632cb1ec752ba058ef533540929c9af7b61d489e 100644 GIT binary patch delta 1338 zcmZ`(U2GIp6#njXW@lR3(wY71wyfPse^_L*>{{xB32qIxwa_9q#nP>%Q`*HQLQT65 zq9)zMfC-vNJtp;`iX>FdD;iFIV4eB#Euh2CkK)3aFx@vUNk9vSQjikB_Cxp{fI;Yk&;u};!4B|6v z#1JTk8>~{z`WobubfdrZhn8RRDng2ilib? zYa-V4@3X4e&QYZcFA^8BYH zA2jNVJ|B`k>*n8S3B#O34Tq6<*#q28MOxkDBwkv?S8K4De((nMCko0fzNp=r_a9-_ zu7TIBf#<8sG7nWf?v_aeU7J`d)>@hYcbA?hWV_236UJScb6tOV+Mfl=L6`bB(6>7+<<<*y zyZ;a8{I1{h=`wkg?-1-5%` zUj7f;lI*4e+mh_&0^2=(LwPne_BD(B)ZG^o!}KOwo4#N>LO-!RK-%7z7^NrKj*-na zL+?v_Vee3-n=fR6*;AZT{T~ab=cU($vwdJzd_5RY^z9`_|C#^&pc5YYStr|l?rFEovZys2i?2Cb4Oi_Y?acfOs>>i|LRyr70n%!3$AiNR#$p>%mApG||K&2f;VHtESbY^Gn|Q zz4t!vJHL7PO?IBM^L$ZNxE`AF11H>{l}Xmab${J_Z5l)BIPb)=+UzePqE&ftQr)P% z<3)IwNxk5u)TgCtEhND;ENgW^jkuBeXh_y5VXvM-x4ssq^`vqxjoSHI^^W*=MN3m}$27TpN5kD>dl0SlkzY%wQHh%SQ#dXOQ2g3N+_X>{qcca1| zb}IrWR4qnRWMDEF;V%3V9E+FHkK`vFp#18hxSVv9DpiN3De$x~KvHrKhE6ItZ(5o$R8W!0jhZnNG`KYe!Qmb*T>XuGf09*;)P zz9AdoFym!6US1JF!Thlwt+7_ASHhk2PakD*H LPhl5!9oX>*@$4IE diff --git a/src/test/resources/dataformat/dataformat.xlsx b/src/test/resources/dataformat/dataformat.xlsx index 0085930c31d5b3a08eb63f6f868089eb89c6a29d..9f41f274801a008d8e96a12c8a0c31e6f5165216 100644 GIT binary patch delta 6381 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 delta 6401 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 L2VI`)ALPFP?t%%5