2013-01-25 1 views
15

Apache POIでMS Office Excelのファイルタイプを判別する方法はありますか? Excel 97(-2007)(.xls)またはExcel 2007 OOXML(.xlsx)では、Excelファイルがどの形式であるかを知る必要があります。Apache POIでMS Excelのファイルタイプを確認する

は、私はこのような何かを行うことができたとします

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

感謝を。

を使用でき
+1

なぜ前を知る必要がありますか? WorkbookFactoryを使用して適切なタイプを作成することはできませんか? – Gagravarr

+0

これはまた良い変種です、ありがとう。 –

答えて

35

...

、ファイルと特別な何かをするつもりなら、その後、rjokelai's answerはそれを行う方法です。

しかし、HSSF/XSSF/Common SSユースモデルを使用している場合は、POIを使用する方が簡単です。WorkbookFactoryを使用すると、タイプが検出されて開かれます。それはHSSFWorkbookまたはXSSFWorkbookだ場合は特別な何か、テストを行うために必要な場合は、

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

または

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

:あなたが何かのようにしてください。ファイルを開くときに、遅くなりメモリを節約するためにuse a File rather than an InputStream if possible

ファイルが何であるかわからない場合は、Apache Tikaを使用して検出してください。膨大な数の異なるファイル形式を検出できます。我々は、WorkbookFactoryのロジックを模倣する無関係なビットを削除し、代わりに、ファイルタイプを返すことができorg.apache.poi.ss.usermodel.WorkbookFactory#create(java.io.InputStream)

のlibの実装に基づいて

+0

Thanks Gagravarr ! –

21

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

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

これらは基本的にWorkbookFactory#create(InputStream)がタイプ

を決定するために使用する方法です両方の方法は、唯一の「マーク」機能(またはPushBackInputStream)をサポートするストリームサポートしていることに注意してください、単純なFileInputStreamはサポートされていません。 BufferedInputStreamをラッパーとして使用します。この理由から、検出後、開始点にリセットされるので、単にストリームを再利用することができます。答えにコメントを推進

+1

ありがとうございます。これは、大規模なExcelファイルを処理するために低レベルのイベントベースの読み取り専用アクセスを使用しているときにファイルの種類を検出する唯一の方法です。 – SWilk

+1

"マークする"ストリームのみを使用できるという情報を追加しました。更新されたコードサンプル。 –

+0

メソッド 'hasOOXMLHeader'がクラス' POIXMLDocument'内で控除され、クラス[DocumentFactoryHelper](https://poi.apache.org/apidocs/org/apache/poi/poifs/filesystem/DocumentFactoryHelper.html)内で使用されます – KAD

1

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 
} 
関連する問題