如何使用OLEDB获取Excel中的唯一Excel工作表名称列表;过滤掉显示在元数据中的非工作表

时间:2012-05-18 14:24:25

标签: c# excel oledb

我在使用OLEDB从Excel电子表格中获取工作表名称时遇到问题。问题是,当我使用GetOleDbSchemaTable时,生成的DataTable不仅仅包含实际的工作表名称;它有“表”的额外行,我只能假设它们由Excel内部使用。

例如,如果我有一个名为myWorksheet的工作表,下面的代码最终可能会包含一个包含myWorksheet $,myWorksheet $ PrintTable和myWorksheet $ _的列表。只有第一个myWorksheet $记录用于实际工作表。其他人只是我不需要的垃圾。当您在元数据中查看它们时,它们看起来就像常规表,即使是TABLE类型。

现在我只是手动过滤出名称中带有“$ _”或“$ Print”的内容,但是谁知道其他Excel功能可能会使这些额外的记录以不同的格式出现。

有没有人知道获取实际工作表名称的最佳方法,而不是这些不是工作表的内部表?元数据中是否存在可以区分它们的东西?

 private ArrayList getXlsWorksheetNames(OleDb.OleDbConnection conn)
    {
        ArrayList wsList = new ArrayList();
        DataTable schemaTable;

        try
        {
            conn.Open();
            schemaTable = conn.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, null);

            foreach (DataRow row in schemaTable.Rows)
            {
                //form.appendToResultsTxt("Adding worksheet to list: " + Environment.NewLine +
                //    "Name = " + row.Field<string>("TABLE_NAME") + "," + Environment.NewLine +
                //    "Type = " + row.Field<string>("TABLE_TYPE") + "," + Environment.NewLine + Environment.NewLine);
                wsList.Add(row.Field<string>("TABLE_NAME"));
            }
            conn.Close();
        }
        catch (Exception ex)
        {
            if (this.mode == Cps2TxtUtilModes.GUI_MODE)
            {
                this.form.appendToResultsTxt(ex.ToString());
            }
            throw;
        }

        return wsList;
    }

我在这个链接上阅读了这篇文章,但他们似乎没有做任何与我不同的事情,而且我没有看到任何过滤掉额外的非工作表,所以微软似乎没有提供了正确的答案。

http://support.microsoft.com/kb/318452

我也看了很多StackOverflow,就像下面链接中的线程有帮助,但是没有解决这个问题。

Using Excel OleDb to get sheet names IN SHEET ORDER

在有人要求之前,我还想说我无法控制电子表格中使用的功能,所以我不能告诉他们“不要打开过滤”或“不要”不使用打印表“。

非常感谢任何想法。谢谢!

4 个答案:

答案 0 :(得分:4)

问题是陈旧的,但对于那些现在发现它的人来说,可以像Jim发现的那样跳过......

// skip those that do not end correctly
foreach (DataRow row in schemTable.Rows)
{
    string sheetName = row["TABLE_NAME"].ToString();
    if (!sheetName.EndsWith("$") && !sheetName.EndsWith("$'"))
        continue;
    Console.WriteLine(sheetName);
}

这是想要的人或以$结尾的人或以$'结尾的人。

答案 1 :(得分:2)

根据经验,似乎所有那些名字以美元符号结尾的人。我遇到了来自客户的情况,其中出现了额外的工作表,这些工作表似乎没有出现在数据中 - 后来证明它们是Excel中隐藏的工作表!

答案 2 :(得分:0)

我想到的第一种方式与链接中列出的akash88相同 Using Excel OleDb to get sheet names IN SHEET ORDER链接。

您可以采用akash88的方法并将其清理一下,以便更好地阅读代码。

        var wsList = from s in schemaTable
                     where s.Field<string>("TABLE_NAME").Contains("$")
                     select s.Field<string>("TABLE_NAME");

答案 3 :(得分:0)

您可以测试EndsWith("$")而不是Contains("$"),如下所示:

List<String> lstsheetNames = new List<String>();
String sheetName;
foreach (DataRow row in schemaTable.Rows)
{
    sheetName = row.Field<string>("TABLE_NAME");
    String strTemp = sheetName.Split(' ');

    if(strTemp.Length == 1 && sheetName.EndsWith("$"))
       lstsheetNames.Add(sheetName.Substring(0, sheetName.Length - 1));

    else if(strTemp.Length > 1 && strTemp.GetValue(strTemp.Length - 1).ToString().EndsWith("$'"))
       lstsheetNames.Add(sheetName.Substring(1, sheetName.Length - 3));
}

我在同一个问题中使用过此代码,但效果很好。

编辑抱歉,我没注意到这一点。我现在更改了代码。它可能不是最好或最短的方式,但它有效。