diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index c081818..dcf1d84 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -1,5 +1,11 @@ package com.alibaba.excel.analysis; +import java.io.InputStream; + +import org.apache.poi.poifs.crypt.Decryptor; +import org.apache.poi.poifs.filesystem.DocumentFactoryHelper; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.util.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,17 +45,38 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { } private void choiceExcelExecutor() throws Exception { - ExcelTypeEnum excelType = analysisContext.readWorkbookHolder().getExcelType(); + ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder(); + ExcelTypeEnum excelType = readWorkbookHolder.getExcelType(); if (excelType == null) { - excelExecutor = new XlsxSaxAnalyser(analysisContext); + excelExecutor = new XlsxSaxAnalyser(analysisContext, null); return; } switch (excelType) { case XLS: - excelExecutor = new XlsSaxAnalyser(analysisContext); + POIFSFileSystem poifsFileSystem = null; + if (readWorkbookHolder.getFile() != null) { + poifsFileSystem = new POIFSFileSystem(readWorkbookHolder.getFile()); + } else { + poifsFileSystem = new POIFSFileSystem(readWorkbookHolder.getInputStream()); + } + // So in encrypted excel, it looks like XLS but it's actually XLSX + if (poifsFileSystem.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { + InputStream decryptedStream = null; + try { + decryptedStream = DocumentFactoryHelper.getDecryptedStream(poifsFileSystem.getRoot(), null); + excelExecutor = new XlsxSaxAnalyser(analysisContext, decryptedStream); + return; + } finally { + IOUtils.closeQuietly(decryptedStream); + // as we processed the full stream already, we can close the filesystem here + // otherwise file handles are leaked + poifsFileSystem.close(); + } + } + excelExecutor = new XlsSaxAnalyser(analysisContext, poifsFileSystem); break; case XLSX: - excelExecutor = new XlsxSaxAnalyser(analysisContext); + excelExecutor = new XlsxSaxAnalyser(analysisContext, null); break; default: } diff --git a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index 8df8bfd..996e33a 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -14,10 +14,7 @@ import org.apache.poi.hssf.eventusermodel.HSSFListener; import org.apache.poi.hssf.eventusermodel.HSSFRequest; import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener; import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; -import org.apache.poi.hssf.record.ExtendedFormatRecord; import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.StyleRecord; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; @@ -38,7 +35,6 @@ import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.read.listener.event.EachRowAnalysisFinishEvent; import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.holder.ReadRowHolder; -import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.util.CollectionUtils; /** @@ -58,7 +54,7 @@ import com.alibaba.excel.util.CollectionUtils; */ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor { private boolean outputFormulaValues = true; - private POIFSFileSystem fs; + private POIFSFileSystem poifsFileSystem; private int lastRowNumber; private int lastColumnNumber; private boolean notAllEmpty = false; @@ -73,16 +69,10 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor { private List recordHandlers = new ArrayList(); private AnalysisContext analysisContext; - public XlsSaxAnalyser(AnalysisContext context) throws IOException { + public XlsSaxAnalyser(AnalysisContext context, POIFSFileSystem poifsFileSystem) throws IOException { this.analysisContext = context; this.records = new TreeMap(); - ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder(); - if (readWorkbookHolder.getFile() != null) { - this.fs = new POIFSFileSystem(readWorkbookHolder.getFile()); - } else { - this.fs = new POIFSFileSystem(readWorkbookHolder.getInputStream()); - } - + this.poifsFileSystem = poifsFileSystem; } @Override @@ -110,7 +100,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor { } try { - factory.processWorkbookEvents(request, fs); + factory.processWorkbookEvents(request, poifsFileSystem); } catch (IOException e) { throw new ExcelAnalysisException(e); } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java index bda0e76..748306a 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -53,12 +53,12 @@ public class XlsxSaxAnalyser implements ExcelExecutor { */ private StylesTable stylesTable; - public XlsxSaxAnalyser(AnalysisContext analysisContext) throws Exception { + public XlsxSaxAnalyser(AnalysisContext analysisContext, InputStream decryptedStream) throws Exception { this.analysisContext = analysisContext; // Initialize cache ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder(); - OPCPackage pkg = readOpcPackage(readWorkbookHolder); + OPCPackage pkg = readOpcPackage(readWorkbookHolder, decryptedStream); PackagePart sharedStringsTablePackagePart = pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType()).get(0); @@ -134,17 +134,26 @@ public class XlsxSaxAnalyser implements ExcelExecutor { readWorkbookHolder.getReadCache().putFinished(); } - private OPCPackage readOpcPackage(ReadWorkbookHolder readWorkbookHolder) throws Exception { - if (readWorkbookHolder.getFile() != null) { + private OPCPackage readOpcPackage(ReadWorkbookHolder readWorkbookHolder, InputStream decryptedStream) + throws Exception { + if (decryptedStream == null && readWorkbookHolder.getFile() != null) { return OPCPackage.open(readWorkbookHolder.getFile()); } if (readWorkbookHolder.getMandatoryUseInputStream()) { - return OPCPackage.open(readWorkbookHolder.getInputStream()); + if (decryptedStream != null) { + return OPCPackage.open(decryptedStream); + } else { + return OPCPackage.open(readWorkbookHolder.getInputStream()); + } } File readTempFile = FileUtils.createCacheTmpFile(); readWorkbookHolder.setTempFile(readTempFile); File tempFile = new File(readTempFile.getPath(), UUID.randomUUID().toString() + ".xlsx"); - FileUtils.writeToFile(tempFile, readWorkbookHolder.getInputStream()); + if (decryptedStream != null) { + FileUtils.writeToFile(tempFile, decryptedStream); + } else { + FileUtils.writeToFile(tempFile, readWorkbookHolder.getInputStream()); + } return OPCPackage.open(tempFile); } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java new file mode 100644 index 0000000..733f1a2 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java @@ -0,0 +1,38 @@ +package com.alibaba.easyexcel.test.temp; + +import java.io.File; +import java.io.FileInputStream; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.fastjson.JSON; + +/** + * 临时测试 + * + * @author Jiaju Zhuang + **/ +@Ignore +public class LockTest { + private static final Logger LOGGER = LoggerFactory.getLogger(LockTest.class); + + @Test + public void test() throws Exception { + + List list = + EasyExcel.read(new FileInputStream("D:\\test\\t222.xlsx")).sheet().headRowNumber(0).doReadSync(); + for (Object data : list) { + LOGGER.info("返回数据:{}", JSON.toJSONString(data)); + } + list = EasyExcel.read(new File("D:\\test\\t222.xlsx")).sheet().headRowNumber(0).doReadSync(); + for (Object data : list) { + LOGGER.info("返回数据:{}", JSON.toJSONString(data)); + } + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java index edabcec..ece50bd 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java @@ -1,5 +1,6 @@ package com.alibaba.easyexcel.test.temp; +import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.lang.reflect.Field; @@ -10,6 +11,8 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.poifs.crypt.Decryptor; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DataFormatter; @@ -19,7 +22,6 @@ import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.tomcat.util.http.fileupload.IOUtils; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; @@ -91,7 +93,7 @@ public class StyleTest { @Test public void poi0701() throws Exception { InputStream is = new FileInputStream("D:\\test\\f1.xlsx"); - Workbook workbook = WorkbookFactory.create(is); // 这种方式 Excel 2003/2007/2010 都是可以处理的 + Workbook workbook = WorkbookFactory.create(is); Sheet sheet = workbook.getSheetAt(0); print(sheet.getRow(0).getCell(0)); print(sheet.getRow(1).getCell(0)); @@ -99,6 +101,44 @@ public class StyleTest { print(sheet.getRow(3).getCell(0)); } + @Test + public void poi0702() throws Exception { + Workbook workbook = WorkbookFactory.create(new FileInputStream("D:\\test\\t2.xlsx")); + workbook = WorkbookFactory.create(new File("D:\\test\\t2.xlsx")); + Sheet sheet = workbook.getSheetAt(0); + Row row = sheet.getRow(0); + System.out.println(row.getCell(0).getNumericCellValue()); + } + + @Test + public void poi0703() throws Exception { + try { + POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream("D:\\test\\t2.xlsx")); + System.out.println(poifsFileSystem.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)); + } catch (Exception e) { + e.printStackTrace(); + } + + try { + POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new File("D:\\test\\t2.xlsx")); + System.out.println(poifsFileSystem.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)); + } catch (Exception e) { + e.printStackTrace(); + } + try { + POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream("D:\\test\\t222.xlsx")); + System.out.println(poifsFileSystem.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)); + } catch (Exception e) { + e.printStackTrace(); + } + try { + POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new File("D:\\test\\t222.xlsx")); + System.out.println(poifsFileSystem.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)); + } catch (Exception e) { + e.printStackTrace(); + } + } + private void print(Cell cell) { System.out.println( DateUtil.isADateFormat(cell.getCellStyle().getDataFormat(), cell.getCellStyle().getDataFormatString()));