exceldatareader 支持 .xls 和 .xlsx,但需匹配对应方法:createbinaryreader 读 .xls(ole 格式),createopenxmlreader 读 .xlsx(openxml 格式);用错抛 invalidoperationexception;推荐用 createreader 自动识别文件头,但不支持 .xlsb 或加密文件。

ExcelDataReader 支持 .xls 和 .xlsx 吗?
支持,但必须选对版本和驱动。ExcelDataReader 本身不直接解析二进制格式,而是通过底层引擎区分处理:ExcelReaderFactory.CreateBinaryReader 用于旧版 .xls(OLE Compound Document 格式),ExcelReaderFactory.CreateOpenXmlReader 用于新版 .xlsx(ZIP+XML 格式)。用错方法会直接抛 System.InvalidOperationException: Invalid file format。
读取 .xls 文件时常见报错及修复
最典型的是 System.IO.FileFormatException: OLE compound document is invalid,通常因为:
- 文件实际是加密的(即使没密码提示,也可能被 Office 自动加密),ExcelDataReader 不支持解密
- 传入了空流或已关闭的
FileStream,需确保FileMode.Open+FileAccess.Read+ 流未被释放 - 误用了
CreateOpenXmlReader去读.xls—— 必须用CreateBinaryReader
正确写法示例:
using var stream = File.Open("data.xls", FileMode.Open, FileAccess.Read);
using var reader = ExcelReaderFactory.CreateBinaryReader(stream); // 注意这里
while (reader.Read()) {
Console.WriteLine(reader.GetString(0));
}
读取 .xlsx 文件要注意编码和内存占用
.xlsx 是基于 OpenXML 的压缩包,CreateOpenXmlReader 默认使用 XmlReader 流式解析,不加载整个文档到内存,但有两点易忽略:
- 中文列名或单元格内容若含 BOM 或乱码,不是编码问题,而是 Excel 自身存储为 UTF-16 但未声明,
reader.GetString(i)会自动处理,无需手动转码 - 如果调用
AsDataSet(),它会把所有 Sheet 全部加载进内存 —— 处理大文件(>5MB)时容易OutOfMemoryException,建议用逐行Read()+GetValue(i) -
.xlsx文件若由 LibreOffice 或 WPS 生成,可能缺少必要 XML 命名空间,导致XmlException;此时可降级用CreateReader(自动检测格式),但它内部仍会先尝试 OpenXml,失败才 fallback 到 Binary
如何统一处理两种格式而不报错?
用 ExcelReaderFactory.CreateReader 最省事,它会自动 sniff 文件头(前 8 字节)判断格式:
-
.xls开头是D0 CF 11 E0 A1 B1 1A E1→ 走 BinaryReader -
.xlsx开头是50 4B 03 04(ZIP signature)→ 走 OpenXmlReader
但注意:该方法返回的是 IExcelDataReader,不是具体类型,无法调用 IsFirstRowAsColumnNames 等扩展属性,需手动设置列名逻辑。另外,它不支持 .xlsb 或加密文件,遇到就直接抛异常,没有静默 fallback。
真正难处理的其实是混合场景:用户上传文件后缀是 .xls,但内容实为 .xlsx(比如重命名所致),这种靠扩展名判断必挂 —— 唯一可靠方式是读文件头,而不是依赖 Path.GetExtension。







