如何在Excel中使用OLEDB获得只有excel工作表名称的列表; 过滤出在元数据中显示的非工作表
我有一个使用OLEDB从Excel电子表格中获取工作表名称的问题。 问题是,当我使用GetOleDbSchemaTable时,生成的DataTable不仅仅是实际的工作表名称; 它有额外的“表”,我只能假设由Excel内部使用的行。
例如,如果我有一个名为myWorksheet的工作表,下面的代码最终可能会包含一个包含myWorksheet $,myWorksheet $ PrintTable和myWorksheet $ _的列表。 只有第一个myWorksheet $logging是实际的工作表。 其他人只是垃圾,我不需要。 在元数据中查看它们时,它们看起来就像常规表一样,即使使用TABLEtypes也是如此。
现在我只是用名字“$ _”或者“$ Print”手动过滤掉了所有的东西,但是谁知道Excel的其他function可能会使这些额外的logging以不同的格式出现。
有谁知道只有实际的工作表名称的最佳方式,而不是这些不是工作表的内部表? 元数据中是否有东西可以区分它们?
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来获取表格名称
在任何人提出问题之前,我还想说,我并不能真正控制电子表格中使用的function,所以我不能只告诉他们“不要打开过滤”或“不要使用打印表格“。
任何想法都非常感激。 谢谢!
这个问题是古老的,但是对于那些现在发现它的人来说,吉姆发现可以跳过…
// 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); }
那就是那些以$
结尾的或者以$'
结尾的那些。
从经验来看,似乎是所有名字以美元符号结尾的人。 我遇到了客户的情况,那些额外的工作表似乎出现在数据中,而这些情况在后来被certificate是隐藏在Excel中的工作表!
我想到的第一种方法与akash88在使用Excel OleDb链接中列出的方法获取表单名称在“订单”链接中的方式相同。
你可以采取akash88的方法,并清理一点,所以代码更好阅读。
var wsList = from s in schemaTable where s.Field<string>("TABLE_NAME").Contains("$") select s.Field<string>("TABLE_NAME");
您可以testingEndsWith("$")
而不是像下面这样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)); }
我用这个代码在同一个问题,它工作正常。
编辑:对不起,我没有注意到这一点。我现在改变了代码。它可能不是最好的或最短的方式,但它的工作原理。