获取 Excel 文件中的所有工作表名称,可以通过 OleDbConnection 获取表架构

1. Microsoft.Jet.OLEDB.4.0 提供程序:
    用于支持 Excel 972003 (.xls) 文件格式。
    Extended Properties="Excel 8.0;HDR=YES;IMEX=1":Excel 8.0 表示 .xls 格式,HDR=YES 表示第一行作为列名,IMEX=1 用于处理混合数据类型的情况。

2. Microsoft.ACE.OLEDB.12.0 提供程序:
    用于支持 .xlsx 文件格式。

using System;
using System.Data;
using System.Data.OleDb;

class ExcelSheetNames
{
    public static void Main(string[] args)
    {
        // Excel文件的路径
        string fileName = "your_excel_file_path_here";  // 替换为实际文件路径
        string connString;

        // 根据文件格式选择连接字符串
        if (fileName.EndsWith(".xls"))
        {
            connString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
                         "Data Source=" + fileName + ";" +
                         "Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\";ReadOnly=True;";
        }
        else if (fileName.EndsWith(".xlsx"))
        {
            connString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
                         "Data Source=" + fileName + ";" +
                         "Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\";ReadOnly=True;";
        }
        else
        {
            Console.WriteLine("不支持的文件格式");
            return;
        }

        // 创建连接对象
        OleDbConnection objConn = new OleDbConnection(connString);

        try
        {
            // 尝试打开数据库连接
            objConn.Open();

            // 获取Excel文件中的数据表(工作表)信息
            DataTable dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

            // 遍历DataTable,获取所有工作表的名称
            foreach (DataRow row in dt.Rows)
            {
                // 读取表名,通常表名以 "$" 结尾
                string sheetName = row["TABLE_NAME"].ToString();
                
                // 输出工作表名称
                Console.WriteLine(sheetName);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("出现错误: " + ex.Message);
        }
        finally
        {
            // 关闭连接
            if (objConn.State == ConnectionState.Open)
            {
                objConn.Close();
            }
        }
    }
}

使用 OpenXML 获取 Excel 文件中的工作表名称通常比通过 OleDbConnection 方式更高效,特别是当你只需要读取结构信息(如工作表名称)而不是整个数据表时。主要有以下几个原因:

 OpenXML 优势:
1. 轻量级和高效:OpenXML 不依赖于安装外部驱动程序(如 OLEDB 驱动),并且直接操作 Excel 文件的 XML 结构,因此更轻量,效率更高,特别是只获取工作表信息时。
2. 无文件锁定问题:OpenXML 以只读方式访问文件,不受 Excel 文件是否被打开的限制,不会遇到文件锁定的问题。
3. 不需要额外配置:使用 OleDbConnection 时,你需要考虑不同的连接字符串(如 Jet 和 ACE 提供程序),而 OpenXML 仅需要 .xlsx 文件格式(不支持 .xls)。
4. 跨平台支持:OpenXML 是纯托管代码,因此在不同平台上(如 Windows 和 Linux)都能运行,而 OLEDB 是 Windows 专有的技术。

 OpenXML 获取工作表名称示例代码:csharp

using System;
using DocumentFormat.OpenXml.Packaging;
using System.Linq;

class ExcelSheetNames
{
    public static void Main(string[] args)
    {
        // Excel文件的路径
        string fileName = "your_excel_file_path_here";  // 替换为实际文件路径

        try
        {
            // 打开Excel文档
            using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false))
            {
                // 获取工作簿的结构
                var workbookPart = document.WorkbookPart;
                
                // 遍历所有的工作表
                var sheets = workbookPart.Workbook.Sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>();
                
                foreach (var sheet in sheets)
                {
                    // 输出每个工作表的名称
                    Console.WriteLine("Sheet Name: " + sheet.Name);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("出现错误: " + ex.Message);
        }
    }
}


 代码说明:
1. SpreadsheetDocument.Open:通过 OpenXML 的 SpreadsheetDocument 打开 Excel 文件。这是一个只读操作(第二个参数为 false),所以即使文件被占用,也可以安全读取。
   
2. workbookPart.Workbook.Sheets:获取工作簿中的 Sheets 集合,包含所有的工作表信息。

3. 遍历工作表:每个 Sheet 对象有一个 Name 属性,表示工作表的名称。

4. 异常处理:捕获任何可能的异常,如文件路径错误、格式错误等。

 OpenXML vs OleDbConnection 性能比较:

 读取速度:如果只获取工作表名称,OpenXML 的速度通常更快,因为它直接解析文件的 XML 结构,而不需要创建复杂的数据库连接和查询。
  
 资源使用:OpenXML 是轻量级的库,内存和 CPU 占用更低,而 OleDbConnection 需要加载外部提供程序(如 ACE.OLEDB),相对较重。

 文件类型支持:OpenXML 仅支持 .xlsx 格式,不支持旧版本的 .xls 文件。如果你需要处理 .xls,则 OleDbConnection 是必要的。

 总结:
如果你只需要读取 .xlsx 文件的工作表名称,并希望避免文件锁定问题或配置复杂性,OpenXML 是更高效、可靠的选择。OleDbConnection 虽然功能强大,但主要适用于需要读取和操作数据的场景。

OleDbConnection 和 OpenXML 之间的效率差异取决于多个因素,包括你的操作场景、数据量以及使用方式。以下是对两者的效率分析,帮助理解在不同场景下的性能表现。

 1. OleDbConnection 性能分析
   
优点:
 处理复杂查询: 如果需要对 Excel 文件进行复杂的数据查询、过滤或聚合,OleDbConnection 的 SQL 查询能力会更有效率。你可以像查询数据库一样对 Excel 数据进行操作。
 支持 .xls 文件: OleDbConnection 可以处理早期的 .xls 格式文件,以及 .xlsx 格式。
  
缺点:
 外部依赖: 需要外部 OLEDB 驱动,可能存在驱动安装问题和兼容性问题,尤其是在不同系统环境下。
 开销较大: 打开连接时需要额外的系统资源开销,比如加载提供程序、创建数据库连接等。
 文件锁定问题: 如果文件被 Excel 打开,可能会遇到文件锁定,导致无法读取。
 效率较低: 对于仅需要读取元数据(如工作表名称)或轻量级的读取操作,OleDbConnection 的性能可能不如 OpenXML,因为它相当于模拟数据库查询,开销较大。

 2. OpenXML 性能分析

优点:
 高效读取元数据: OpenXML 直接读取 Excel 文件的 XML 结构,尤其是像获取工作表名称这种元数据操作,速度非常快,几乎没有多余的系统资源消耗。
 无外部依赖: 不需要依赖外部驱动或提供程序,避免了配置问题。
 无文件锁定问题: 可以在 Excel 文件被打开时以只读方式访问文件,避免文件锁定问题。
 轻量级: 适用于仅读取或操作 Excel 文件结构的场景,如读取工作表名称、读取单元格内容等。

缺点:
 只支持 .xlsx 文件: OpenXML 不支持 .xls 文件,只能用于处理基于 XML 的 Excel 文件格式(Office 2007 及更高版本的 .xlsx 文件)。
 无复杂查询功能: 不能像 OleDbConnection 一样使用 SQL 进行复杂的数据查询,OpenXML 只提供基础的文件读取和写入功能。

 3. 性能对比:实际场景

 读取工作表名称: 
   对于只需要获取 Excel 文件中的工作表名称,OpenXML 明显更快。因为 OpenXML 直接从文件的 XML 结构中读取工作表信息,省去了建立数据库连接的开销。而 OleDbConnection 需要建立连接、创建查询,并返回结果,这一过程相对慢。
  
 大数据量读取:
   如果需要从 Excel 中读取大量数据,OleDbConnection 和 OpenXML 的性能取决于数据操作方式。OleDbConnection 可以使用 SQL 进行筛选和聚合,因此在某些特定情况下可能表现更好。而 OpenXML 则直接从文件结构中逐行读取数据,适合批量导出,但没有高级查询功能。
  
 文件格式:
   如果你的文件是 .xls 格式(Excel 972003),OleDbConnection 是必要的,因为 OpenXML 不支持该格式。
   如果是 .xlsx 格式文件,OpenXML 通常在性能上表现更好,尤其是对于简单的读取操作。

 4. 定量性能差异示例

假设场景:从 Excel 文件中获取所有工作表名称,并且文件大小为几MB(中等大小)。

 OleDbConnection:
   初始化 OLEDB 提供程序并建立连接耗时约 100ms  200ms(具体时间取决于系统环境和驱动程序)。
   获取工作表名称的操作时间约为 几十毫秒(因为它需要执行 SQL 查询)。
  
 OpenXML:
   打开文件并直接读取工作表名称耗时约 10ms  50ms。因为不需要数据库连接和查询,OpenXML 更适合这种轻量级操作。

 5. 结论

 OpenXML 更快: 对于获取元数据(如工作表名称)或处理较小的 Excel 文件,OpenXML 在效率上显著优于 OleDbConnection,尤其是在不需要数据库功能的情况下。
 OleDbConnection 更强大: 在需要进行复杂的查询、筛选或聚合操作时,OleDbConnection 通过 SQL 查询功能可能更具优势,但这会增加性能开销。

 适用场景总结:
 简单读取(如获取工作表名称)或文件结构操作:OpenXML 是最佳选择,轻量且高效。
 需要对 .xls 和 .xlsx 文件进行兼容,或需要执行复杂查询:使用 OleDbConnection 较为合适,尽管它在性能上稍逊,但支持更多功能。

上一篇:【Linux】实现一个简易的shell命令行


下一篇:清理数据库中的某个部门树-解决