2014-03-06 162 views
0

我的問題看起來很瑣碎,但儘管我進行了大量的研究,但我還沒有找到答案。有沒有辦法知道文件名是否是Excel格式?

.NET中有一種方法可以知道文件名是否是Excel電子表格嗎?

我對特定的擴展名(.xls,.xlsx等)不感興趣,我只想知道該文件是否是一個優秀的通用電子表格。

+1

你需要尋找Magic Number™:) –

+0

你能告訴我更多關於它嗎? –

+1

是否有一個原因,你想這樣做,而不是創建一個包含Excel電子表格的所有已知文件擴展名的列表,並查看文件擴展名是否在該列表中? –

回答

1

,我這裏寫類似的東西是代碼:

private enum Extensions 
{ 
    Unknown = 0, 
    DocOrXls, 
    Pdf, 
    Jpg, 
    Png, 
    DocxOrXlsx, 
} 

private static readonly Dictionary<Extensions, string> ExtensionSignature = new Dictionary<Extensions, string> 
    { 
     {Extensions.DocOrXls, "D0-CF-11-E0-A1-B1-1A-E1"}, 
     {Extensions.Pdf, "25-50-44-46"}, 
     {Extensions.Jpg, "FF-D8-FF-E"}, 
     {Extensions.Png, "89-50-4E-47-0D-0A-1A-0A"}, 
     {Extensions.DocxOrXlsx, "50-4B-03-04-14-00-06-00"} 
    }; 

private static string GetExtension(byte[] bytes) 
{ 
    if (bytes.Length < 8) 
     return string.Empty; 
    var signatureBytes = new byte[8]; 
    Array.Copy(bytes, signatureBytes, signatureBytes.Length); 
    string signature = BitConverter.ToString(signatureBytes); 
    Extensions extension = ExtensionSignature.FirstOrDefault(pair => signature.Contains(pair.Value)).Key; 
    switch (extension) 
    { 
     case Extensions.Unknown: 
      return string.Empty; 
     case Extensions.DocOrXls: 
      if (bytes.Length < 512) 
       break; 
      signatureBytes = new byte[4]; 
      Array.Copy(bytes, 512, signatureBytes, 0, signatureBytes.Length); 
      signature = BitConverter.ToString(signatureBytes); 
      if (signature == "EC-A5-C1-00") 
       return ".doc"; 
      return ".xls"; 
     case Extensions.Pdf: 
      return ".pdf"; 
     case Extensions.Jpg: 
      return ".jpg"; 
     case Extensions.Png: 
      return ".png"; 
     case Extensions.DocxOrXlsx: 
      string fileBody = Encoding.UTF8.GetString(bytes); 
      if (fileBody.Contains("word")) 
       return ".docx"; 
      if (fileBody.Contains("xl")) 
       return ".xlsx"; 
      break; 
     default: 
      throw new ArgumentOutOfRangeException(); 
    } 
    return string.Empty; 
} 
1

您可以創建一個try-catch聲明,看看Excel可以打開文件:很久以前

using Microsoft.Office.Interop.Excel; 

.... 

try 
{ 
    Application app = new Application(); 
    Workbook book = app.Workbooks.Open(@workbookPath); //@workbookpath is the file path 
} 
catch 
{ 
    //Excel encountered an error opening the file at the path 
} 
+0

這將是一個好主意,但excel可以打開一個.txt文件,對嗎? –

+0

@PierreRoudaut這是真的,但它會將行添加到不同的行中,這在技術上可能意味着它可以用作Excel電子表格。 – miguelarcilla

+0

技術上是這樣。我喜歡你的解決方案,但唯一的問題是我得到的文件名是來自Outlook消息。如果我想用excel打開它,我必須將它保存在文件系統的某個地方,這是我希望通過首先篩選擴展名避免的事情之一,如果你明白我的意思。 –

4

你需要閱讀文件標題字節,以便確切知道它是什麼類型的文件。

此庫在這裏FileTypeDetective完全符合你的要求,但看起來像項目不再活躍。無論如何,一旦你明白了,可以很容易地改編/更正。

請參見:

// MS Office files 
     public readonly static FileType WORD = new FileType(new byte?[] { 0xEC, 0xA5, 0xC1, 0x00 }, 512, "doc", "application/msword"); 
     public readonly static FileType EXCEL = new FileType(new byte?[] { 0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00 }, 512, "xls", "application/excel"); 
     public readonly static FileType PPT = new FileType(new byte?[] {0xFD, 0xFF, 0xFF, 0xFF, null, 0x00, 0x00, 0x00 }, 512, "ppt", "application/mspowerpoint"); 

所有您需要做的是找到在所有Excel文件的共同簽名。

我的猜測是,這個庫仍然工作得很好。自2012年以來,我沒有看到這些頭文件發生了更改(最新版本)。

+0

這聽起來比我一直在嘗試的解決方法更優雅,我要挖掘這一點,謝謝! –

相關問題