C# 有没有办法知道文件名是否为Excel格式?
我的问题可能看起来很琐碎,但尽管我做了大量的研究,我还是没有找到答案 在.NET中有没有办法知道文件名是否是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
我对特定扩展名(.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");