使用Apache POI确定MS Excel文件types

有没有办法确定在Apache POI的MS Office Excel文件types? 我需要知道什么格式的Excel文件:在Excel 97(-2007)(.xls)或Excel 2007 OOXML(.xlsx)。

我想我可以做这样的事情:

int type = PoiTypeHelper.getType(file); switch (type) { case PoiType.EXCEL_1997_2007: ... break; case PoiType.EXCEL_2007: ... break; default: ... } 

谢谢。

促进对答案的评论…

如果你打算对这些文件做一些特别的事情,那么rjokelai的回答就是这样做的方法。

但是,如果您只是要使用HSSF / XSSF / Common SS用户模式,那么使用POI为您执行操作要简单得多,并使用WorkbookFactory为您检测并打开types。 你会做这样的事情:

  Workbook wb = WorkbookFactory.create(new File("something.xls")); 

要么

  Workbook wb = WorkbookFactory.create(request.getInputStream()); 

那么如果你需要做一些特别的事情,testing它是HSSFWorkbook还是XSSFWorkbook 。 打开文件时, 尽可能使用File而不是InputStream来加快速度并节省内存。

如果您不知道自己的文件是什么,请使用Apache Tika进行检测 – 它可以为您检测大量不同的文件格式。

您可以使用:

 // For .xlsx POIXMLDocument.hasOOXMLHeader(new BufferedInputStream( new FileInputStream(file) )); // For .xls POIFSFileSystem.hasPOIFSHeader(new BufferedInputStream( new FileInputStream(file) )); 

这些实质上是WorkbookFactory#create(InputStream)用于确定types的方法

请注意,这两种方法只支持支持“标记”function(或PushBackInputStream)的stream,所以不支持简单的FileInputStream。 使用BufferedInputStream作为包装。 出于这个原因,在检测之后,您可以简单地重新使用stream,因为它将被重新设置为起点。

基于org.apache.poi.ss.usermodel.WorkbookFactory#create(java.io.InputStream)的lib实现org.apache.poi.ss.usermodel.WorkbookFactory#create(java.io.InputStream)

我们可以模仿WorkbookFactory的逻辑,删除不相关的位并返回文件types。

 public static TYPE fileType(File file) { try ( InputStream inp = new FileInputStream(file) ) { if (!(inp).markSupported()) { return getNotMarkSupportFileType(file); } return getType(inp); } catch (IOException e) { LOGGER.error("Analyse FileType Problem.", e); return TYPE.INVALID; } } private static TYPE getNotMarkSupportFileType(File file) throws IOException { try ( InputStream inp = new PushbackInputStream(new FileInputStream(file), 8) ) { return getType(inp); } } private static TYPE getType(InputStream inp) throws IOException { byte[] header8 = IOUtils.peekFirst8Bytes(inp); if (NPOIFSFileSystem.hasPOIFSHeader(header8)) { NPOIFSFileSystem fs = new NPOIFSFileSystem(inp); return fileType(fs); } else if (DocumentFactoryHelper.hasOOXMLHeader(inp)) { return TYPE.XSSF_WORKBOOK; } return TYPE.INVALID; } private static TYPE fileType(NPOIFSFileSystem fs) { DirectoryNode root = fs.getRoot(); if (root.hasEntry("EncryptedPackage")) { return TYPE.XSSF_WORKBOOK; } return TYPE.HSSF_WORKBOOK; } public enum TYPE { HSSF_WORKBOOK, XSSF_WORKBOOK, INVALID }