2016-03-05 12 views
1

我使用NPOI庫來讀取xlsx和xls文件。如何檢查IWorkbook對象是否可以從文件流構建?

我有這樣的代碼:

IWorkbook workBook = null; 
string fileExtension = Path.GetExtension(path); 
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 
{ 
    if (fileExtension == ".xls") 
     workBook = new HSSFWorkbook(fs); 
    else if (fileExtension == ".xlsx") 
     workBook = new XSSFWorkbook(fs); 
} 

而且它的工作完美。 但path擅長文件的問題並不總是在他的名字中有擴展名(.xls或.xlsx)。

所以我需要檢查,如果fs suitebale爲HSSFWorkbook()XSSFWorkbook()

任何想法,我怎麼能檢查它沒有文件擴展?

+0

沒有測試過它,但是打開的時候沒有NPOI拋出異常讓我們說* .xlsx就像HSSFWorbook? – VDN

回答

0

申請文件頭信息從https://en.wikipedia.org/wiki/List_of_file_signatures我們可以用這樣的:

public static class FormatRecognizer 
{ 
    public static Boolean IsZipFile(Stream stream) 
    { 
     if (stream == null) 
      throw new ArgumentNullException(paramName: nameof(stream)); 

     var zipHeader = new Byte[] 
     { 
      0x50, 0x4B, 0x03, 0x04 
     }; 

     var streamBytes = GetBytesAndRestore(stream, zipHeader.Length); 
     return streamBytes.SequenceEqual(zipHeader); 
    } 


    public static Boolean IsOffice2003File(Stream stream) 
    { 
     if (stream == null) 
      throw new ArgumentNullException(paramName: nameof(stream)); 

     var officeHeader = new Byte[] 
     { 
      0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, 
     }; 

     var streamBytes = GetBytesAndRestore(stream, officeHeader.Length); 
     return streamBytes.SequenceEqual(officeHeader); 
    } 


    private static IEnumerable<Byte> GetBytesAndRestore(Stream stream, Int32 bytesCount) 
    { 
     if (stream == null) 
      throw new ArgumentNullException(paramName: nameof(stream)); 

     var position = stream.Position; 
     try 
     { 
      using (var reader = new BinaryReader(stream, Encoding.Default, leaveOpen: true)) 
      { 
       return reader.ReadBytes(bytesCount); 
      } 
     } 
     finally 
     { 
      stream.Position = position; 
     } 
    } 
} 

...

private static void PrintFormatInfo(String path) 
{ 
    Console.WriteLine("File at '{0}'", path); 
    using (var stream = File.Open(path, FileMode.Open)) 
    { 
     PrintFormatInfo(stream); 
    } 
} 

private static void PrintFormatInfo(Stream stream) 
{ 
    Console.WriteLine("Is office 2003 = {0}", FormatRecognizer.IsOffice2003File(stream)); 
    Console.WriteLine("Is zip file (possibly xlsx) = {0}", FormatRecognizer.IsZipFile(stream)); 
} 

...

PrintFormatInfo("1.txt"); 
PrintFormatInfo("1.xls"); 
PrintFormatInfo("1.xlsx"); 

它不是絕對可靠,因爲IsZipFile將對簡單的zip存檔返回true,並且IsOffice2003File也將成功處理doc,ppt等。

但這是我能想到的最簡單的解決方案。而任何更正確的事情都需要更深入的文件格式知識,這可能會或可能不是你所需要的。

2
  IWorkbook workBook = null; 
      string fileExtension = Path.GetExtension(path); 

      using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 
      { 
       workBook = WorkbookFactory.Create(fs); 
      } 

WorkbookFactory.Create()方法根據從xls或xlsx文件構建的fileStreem參數構造IWorkbook。

相關問題