有没有一种方法来确定的Apache POI微软Office Excel文件类型? 我需要什么格式的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 /通用SS的usermodel,那么它要简单得多具有POI为你做,并使用WorkbookFactory有检测,为您揭开类型。 你会做这样的事情:
Workbook wb = WorkbookFactory.create(new File("something.xls"));
要么
Workbook wb = WorkbookFactory.create(request.getInputStream());
然后,如果你需要做一些特别的东西,测试,如果它是一个HSSFWorkbook
或XSSFWorkbook
。 打开文件时, 使用一个文件,而不是一个InputStream如果可能加快速度和节省内存。
如果你不知道你的文件是在所有的事,使用Apache的蒂卡做检测-它可以检测到不同的文件格式一个巨大的数字给你。
您可以使用:
// For .xlsx
POIXMLDocument.hasOOXMLHeader(new BufferedInputStream( new FileInputStream(file) ));
// For .xls
POIFSFileSystem.hasPOIFSHeader(new BufferedInputStream( new FileInputStream(file) ));
这些基本上该方法WorkbookFactory#create(InputStream)
用于确定所述类型使用
请注意,这两个方法,仅支持支持“标记”功能(或PushBackInputStream)流,不支持那么简单的FileInputStream。 使用的BufferedInputStream作为包装。 由于这个原因,检测后,你可以简单地重复使用流,因为它会先复位到起点。
这可以通过使用FileMagic类来完成。 请参见下面的JavaDoc - https://poi.apache.org/apidocs/org/apache/poi/poifs/filesystem/FileMagic.html
示例代码段:
FileMagic.valueOf(inputStream).equals(FileMagic.OOXML) // XLSX
基于的lib实施org.apache.poi.ss.usermodel.WorkbookFactory#create(java.io.InputStream)
我们可以模仿WorkbookFactory
的逻辑,去除不相关的位,返回文件类型来代替。
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
}