9

我在使用 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,比如下面链接中的线程,这很有帮助,但不能解决这个问题。

使用 Excel OleDb 在 SHEET ORDER 中获取工作表名称

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

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

4

4 回答 4

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);
}

那是想要的,或者以 结尾的,$或者以 结尾的$'

于 2015-09-30T14:24:45.377 回答
2

根据经验,似乎是所有名字以美元符号结尾的人。我遇到过来自客户的场景,其中似乎出现了数据中不存在的额外工作表——这些后来证明是 Excel 中的隐藏工作表!

于 2012-05-18T15:34:21.450 回答
0

我想到的第一种方式与 使用 Excel OleDb 在 SHEET ORDER 链接中获取工作表名称的链接中列出的 akash88 相同。

您可以采用 akash88 的方法并对其进行一些清理,以便代码更易于阅读。

        var wsList = from s in schemaTable
                     where s.Field<string>("TABLE_NAME").Contains("$")
                     select s.Field<string>("TABLE_NAME");
于 2012-10-05T18:56:48.097 回答
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));
}

我在同样的问题中使用了这段代码,它工作正常。

编辑:对不起,我没有注意这一点。我现在更改了代码。它可能不是最好或最短的方法,但它可以工作。

于 2013-01-28T09:58:56.450 回答