C# 有没有办法知道文件名是否为Excel格式?

C# 有没有办法知道文件名是否为Excel格式?,c#,.net,excel,vb.net,C#,.net,Excel,Vb.net,我的问题可能看起来很琐碎,但尽管我做了大量的研究,我还是没有找到答案 在.NET中有没有办法知道文件名是否是Excel电子表格? 我对特定扩展名(.xls、.xlsx等)不感兴趣,我只想知道该文件是否为excel通用电子表格。您可以创建一个try catch语句,看看excel是否可以打开该文件: using Microsoft.Office.Interop.Excel; .... try { Application app = new Application(); Work

我的问题可能看起来很琐碎,但尽管我做了大量的研究,我还是没有找到答案

在.NET中有没有办法知道文件名是否是Excel电子表格?


我对特定扩展名(.xls、.xlsx等)不感兴趣,我只想知道该文件是否为excel通用电子表格。

您可以创建一个
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
}

很久以前,我写过类似的东西,下面是代码:

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;
}
私有枚举扩展
{
未知=0,
文件,
Pdf,
Jpg,
巴布亚新几内亚,
DocxOrXlsx,
}
私有静态只读字典扩展签名=新字典
{
{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”}
};
私有静态字符串GetExtension(字节[]字节)
{
如果(字节长度<8)
返回字符串。空;
var signatureBytes=新字节[8];
复制(字节,signatureBytes,signatureBytes.Length);
字符串签名=位转换器.ToString(signatureBytes);
Extensions extension=ExtensionSignature.FirstOrDefault(pair=>signature.Contains(pair.Value)).Key;
交换机(分机)
{
案例扩展。未知:
返回字符串。空;
case Extensions.DocOrXls:
如果(字节长度<512)
打破
signatureBytes=新字节[4];
复制(字节,512,signatureBytes,0,signatureBytes.Length);
签名=位转换器.ToString(签名字节);
如果(签名==“EC-A5-C1-00”)
返回“.doc”;
返回“.xls”;
案例扩展.Pdf:
返回“.pdf”;
案例扩展.Jpg:
返回“.jpg”;
case Extensions.Png:
返回“.png”;
case Extensions.DocxOrXlsx:
string fileBody=Encoding.UTF8.GetString(字节);
if(fileBody.Contains(“word”))
返回“.docx”;
if(fileBody.Contains(“xl”))
返回“.xlsx”;
打破
违约:
抛出新ArgumentOutOfRangeException();
}
返回字符串。空;
}

您需要读取文件头字节,以便准确了解文件的类型

这里的库完全满足您的需要,但项目似乎不再处于活动状态。不管怎样,一旦你有了这个想法,你就可以很容易地调整/纠正它

见:

您所要做的就是在所有excel文件中找到一个通用签名


我的猜测是这个图书馆仍然运作良好。我看不出自2012年(上一版本)以来,这些标题有任何更改的原因。

您需要查找神奇的数字™ :)你能告诉我更多关于它的信息吗?你为什么要这样做,而不是仅仅创建一个包含Excel电子表格所有已知文件扩展名的列表,看看文件扩展名是否在该列表中?你可以使用Epplus库。这是个好主意,但Excel可以打开一个.txt文件,对吗?@PierreRoudaut确实如此,但它会将这些行添加到不同的行中,从技术上讲,这可能意味着它可以像Excel电子表格一样工作。我喜欢你的解决方案,但唯一的问题是我得到的文件名来自outlook邮件。如果我想用excel打开它,我必须将它物理地保存在文件系统的某个地方,如果你明白我的意思,这是我想通过首先过滤扩展来避免的事情之一。@Pierreroudout如果是这样,我想你可以编写Outlook脚本(使用
Microsoft.Office.Interop.Outlook
)处理邮件并获取附件。然后,您可以将文件缓存到某个位置,检查Excel是否可以读取该文件,然后将其删除。这不是最好的解决方案,但它是一种潜在的解决方法。我不推荐这种技术。避免仅仅为了验证事物而使用异常。您的代码可能会捕获它,但仍然是一个例外。这听起来比我一直尝试的解决方法更优雅,我将继续深入研究,谢谢!
// 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");