.net - 如何知道流是xlsx、xls还是csv?

标签 .net excel

我知道文件扩展名可以知道它,例如:

void Main()
{
    Console.WriteLine(GetExcelType("xxx.xls")); // Xls
    Console.WriteLine(GetExcelType("xxx.xlsx")); // Xlsx
    Console.WriteLine(GetExcelType("xxx.csv")); // csv
}

// You can define other methods, fields, classes and namespaces here
internal enum ExcelType
{
    Xlsx,Xls,Csv
}

internal ExcelType GetExcelType(string path)
{
    var e = Path.GetExtension(path).ToLowerInvariant();
    switch (Path.GetExtension(path).ToLowerInvariant())
    {
        case ".csv":
            return ExcelType.Csv;
        case ".xlsx":
            return ExcelType.Xlsx;
        case ".xls":
            return ExcelType.Xls;
        default:
            throw new InvalidOperationException("Only allow file extension xlsx,xls,csv");
    } 
}

但如果输入是 Stream,则没有要检查的文件扩展名。

最佳答案

您可以读取流的几个字节并猜测格式。

var buffer = new byte[512];
stream.Read(buffer, 0, buffer.Length);
var magic = BitConverter.ToUInt32(buffer, 0);
switch (magic)
{
  // Old office format (can be any office file)
  case 0xE011CFD0: return ExcelType.Xls;
  // New office format (can be any ZIP archive)
  case 0x04034B50: return ExcelType.Xlsx;
}
// Text file (the bigger the buffer, the more probability)
// Won't work for UTF-16 encoding, but it's rare
if (buffer.All(b => b >= ' ' || b == '\n' || b == '\r' || b == '\t')) return ExcelType.Csv;
throw new InvalidOperationException();

当然,这只是一个猜测,并不能保证流确实是预期的格式,但文件扩展名也不提供任何保证。确保输入格式正确的唯一方法是完全解析它并处理可能发生的任何异常。但这个猜测足以选择尝试哪个解析器。

此外,这还会消耗流中的字节,因此如果您要在检查后使用流,则需要考虑到这一点。如果stream.CanSeek == true,则只需设置stream.Position = 0即可。如果不是,您可以将原始流复制到可以查找的 MemoryStream 中(但这可能需要很多时间);或者实现您自己的流,它将在读取原始流之前提供缓冲区的内容;或者只是确保在读取流的其余部分之前使用缓冲区。

关于.net - 如何知道流是xlsx、xls还是csv?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66731497/

相关文章:

c# - 如何使用 Fluent Nhibernate 映射覆盖将子字符串映射到属性?

c# - 具有 SSL 连接的 RabbitMQ 客户端抛出 SSPI 异常

c# - 监控 exe 何时启动

.net - 在数据库更新期间更改环境

.Net 应用程序死锁和 GC

r - 在 R 中的 Excel 工作簿中获取单元格的格式信息

python - Excel 类似于 pandas 的公式

vba - 当我使用 Range.Cells() 引用单个单元格时出现错误 1004

vba - 从 Excel 中具有多个获胜者的行中选择得分获胜者

excel - R (OSX) 读/写 xls