从.doc文件中区分.xls的正确方法是什么?

我search如何检测该文件是.xls ,我发现了这样的解决scheme(但不弃用):
POIFSFileSystem:

 @Deprecated @Removal(version="4.0") public static boolean hasPOIFSHeader(InputStream inp) throws IOException { return FileMagic.valueOf(inp) == FileMagic.OLE2; } 

但是,对于所有的Microsoft Word文档,例如.doc这个返回true

有没有办法检测.xls文件?

这两个.doc / .xls文档都可以以OLE2存储格式存储。 org.apache.poi.poifs.filesystem.FileMagic可以帮助您检测文件存储格式,而不能单独区分.doc / .xls文件。

另外,POI库中没有任何可用的直接API来确定给定inputstream/文件的文档types(excel或文档)。

下面的例子我有帮助,以确定给定的stream是一个有效的.xls(或.xlsx)文件与警告,它读取给定的inputstram并closures它。

  // slurp content from given input and close it public static boolean isExcelFile(InputStream in) throws IOException { try { // it slurp the input stream Workbook workbook = org.apache.poi.ss.usermodel.WorkbookFactory.create(in); workbook.close(); return true; } catch (java.lang.IllegalArgumentException | org.apache.poi.openxml4j.exceptions.InvalidFormatException e) { return false; } } 

您可能会在此链接上find有关excel文件格式的更多信息

更新 gagravarrbuild议的基于Apache Tika的解决scheme:

 public class TikaBasedFileTypeDetector { private Tika tika; private TemporaryResources temporaryResources; public void init() { this.tika = new Tika(); this.temporaryResources = new TemporaryResources(); } // clean up all the temporary resources public void destroy() throws IOException { temporaryResources.close(); } // return content mime type public String detectType(InputStream in) throws IOException { TikaInputStream tikaInputStream = TikaInputStream.get(in, temporaryResources); return tika.detect(tikaInputStream); } public boolean isExcelFile(InputStream in) throws IOException{ // see https://stackoverflow.com/a/4212908/1700467 for information on mimetypes String type = detectType(in); return type.startsWith("application/vnd.ms-excel") || //for Micorsoft document type.startsWith("application/vnd.openxmlformats-officedocument.spreadsheetml"); // for OpenOffice xml format } } 

在MIMEtypes上看到这个答案 。

您可以使用Apache POI的 HSSF模块 。
这个模型(库)是为读写xls文件而编写的(也是xlsx的最新版本 – 尽pipe它们是不同的语言)。
有了这个代码…

 InputStream ExcelFileToRead = new FileInputStream("FileNameWithLink.xls"); HSSFWorkbook wb = new HSSFWorkbook(ExcelFileToRead); HSSFSheet sheet = wb.getSheetAt(0); 

…你可以检测到它是否是可读的 xls文件。
走得更深,你可以使用这个代码来尝试阅读等等。实际上,这个模块非常易于使用。
可能会有技术上是.xls文件的情况,但它可能不可读(可能存在各种问题)。
Extra – XSSF用于.xlsx ,HSSF用于.xls

我没有使用其他技术,因为我总是想确保我能够稍后阅读该文件。

你可以使用docx4j 。 用OpcPackage.load()加载文件,然后检查内容types。

OpcPackage.load()

  * Convenience method to create a WordprocessingMLPackage * or PresentationMLPackage * from an inputstream (.docx/.docxm, .ppxtx or Flat OPC .xml). * It detects the convenient format inspecting two first bytes of stream (magic bytes). * For office 2007 'x' formats, these two bytes are 'PK' (same as zip file) 

load()返回一个OpcPackage,它是GloxPackage,PresentationMLPackage,SpreadsheetMLPackage,WordprocessingMLPackage所基于的抽象类。 所以这应该适用于word,excel和powerpoint文档。

基本检查

 public final String XLSX_FILE = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"; public final String WORD_FILE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"; public final String UNKNOWN_FILE = "UNKNOWN"; public boolean isFileXLSX(String fileLocation) { return getContentTypeFromFile(fileLocation).equals(XLSX_FILE); } public String getContentTypeFromFile(String fileLocation) { try { return OpcPackage.load(new File(fileLocation)).getContentType(); } catch (Docx4JException e) { return UNKNOWN_FILE; } } 

你应该看到像

 application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml