我在使用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
在有人要求之前,我还想说我无法控制电子表格中使用的功能,所以我不能告诉他们“不要打开过滤”或“不要”不使用打印表“。
非常感谢任何想法。谢谢!
答案 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));
}
我在同一个问题中使用过此代码,但效果很好。
编辑抱歉,我没注意到这一点。我现在更改了代码。它可能不是最好或最短的方式,但它有效。