一言不合先拋個異常
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)
HSSFWorkbook workbook = new HSSFWorkbook(in);
這段異常表示excel版本和workbook的類型不匹配導(dǎo)致的, HSSFWorkbook不支持Excel2007之后的文件版本, poi提供了XSSFWorkbook類型支持后面的版本,
XSSFWorkbook workbook = new XSSFWorkbook(in);
但是這段代碼對老版本的excel不兼容, 查看文檔和源碼發(fā)現(xiàn)HSSFWorkbook和XSSFWorkbook都實現(xiàn)了Workbook接口, 按照網(wǎng)上推薦的方法, 把代碼修改成了
Workbook workbook = null;
try{
workbook = new HSSFWorkbook(in);
}catch(Exception e){
workbook = new XSSFWorkbook(in);
}
然后. 成功的拋出了另一個異常
java.io.IOException: Stream closed
這.... 節(jié)奏不對啊, 進入try塊之后順手把流關(guān)了, 這個方法也搞不定, 難道不用流來做參數(shù)?? 還是先判斷一下流的類型????
怎么判斷???? 我是不會, 好吧, 看文檔, 我相信apache肯定能解決這個問題
好了, 代碼改成了
Workbook workbook = WorkbookFactory.create(in);
一切都正常了. 那么這個方法一定是判斷了文件類型的, 廢話不多說, 貼源碼
public static Workbook create(InputStream inp, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {
// If clearly doesn't do mark/reset, wrap up
if (! inp.markSupported()) {
inp = new PushbackInputStream(inp, 8);
}
// Ensure that there is at least some data there
byte[] header8 = IOUtils.peekFirst8Bytes(inp);
// Try to create
if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
NPOIFSFileSystem fs = new NPOIFSFileSystem(inp);
return create(fs, password);
}
if (DocumentFactoryHelper.hasOOXMLHeader(inp)) {
return new XSSFWorkbook(OPCPackage.open(inp));
}
throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
}
當(dāng)然, maven的依賴要改成這個了
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>