使用本分步指南通过使用与 Microsoft OLE DB Managed Provider 和 Microsoft OLE DB Provider for Jet 的
GetOleDbSchemaTable 方法检索 Microsoft Excel 数据源中的表和列的元数据。
由 Microsoft.NET Framework 的
System.Data.OleDb 类公开的
GetOleDbSchemaTable 方法是.NET
OpenSchema 方法在早期版本的 ActiveX 数据对象 (ADO)。
技术的说明
使用 Microsoft ADO.NET 连接到 Excel 数据源之后,请使用
GetOleDbSchemaTable 方法提取表的元数据的列表。 接下来,使用具有不同的参数相同的方法可以获取所选表的列的元数据。 您还可以使用
DataGridTableStyle 方法进行布局,和格式化数据网格中的查询结果。
要求
以下列表概述了推荐使用的硬件、 软件、 网络的基础结构和所需的服务包:
- Microsoft Visual Studio.NET 兼容的 Microsoft Windows 操作系统上安装。
- 至少一个 Microsoft Excel 工作簿文件 (.xls) 一些行和列数据。
本文假定您熟悉下列主题:
- Microsoft Visual C#.NET 中。
- Microsoft ADO.NET 数据访问。
- Microsoft Excel 工作簿和工作表。
示例
- 启动 Visual Studio.NET 并新建一个 Visual C# Windows 窗体应用程序项目。
- 向 Form 1 中添加三个 按钮 控件和两个的 DataGrid 控件。 更改来分别命名按钮 检索元数据 、 表的列表 ,和 列的列表 , 按钮 控件的 Text 属性。
- 切换到窗体代码模块,然后添加以下语句在任何其他代码之前:
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
- 在在 窗体 类插入以下模块级声明。 使该连接字符串指向包含一些的行和列的数据的 Excel 工作簿文件
private OleDbConnection cn;
private String strCn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\test.xls;Extended Properties=Excel 8.0";
private DataTable dtTables;
private CurrencyManager cm;
private DataTable dtColumns;
private DataView dvColumns;
- 在 窗体 类中的 Windows 窗体设计器生成的代码节之后插入以下代码。 此代码调用 GetOleDbSchemaTable 加载表的并且列列出了、 填充 DataGrids 中,和所选的表更改时更新列列表
private void button1_Click(object sender, System.EventArgs e)
{
GetTablesList();
}
private void GetTablesList()
{
try
{
cn = new OleDbConnection(strCn);
cn.Open();
dtTables = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[]{null,null,null,"TABLE"});
dataGrid1.DataSource = dtTables;
dataGrid1.ReadOnly = true;
cn.Close();
}
catch(System.Data.OleDb.OleDbException myException)
{
for (int i=0; i < myException.Errors.Count; i++)
{
MessageBox.Show("Index #" + i + "\n" +
"Message: " + myException.Errors[i].Message + "\n" +
"Native: " +
myException.Errors[i].NativeError.ToString() + "\n" +
"Source: " + myException.Errors[i].Source + "\n" +
"SQL: " + myException.Errors[i].SQLState + "\n");
}
}
GetColumnsList();
}
private void GetColumnsList()
{
if( cm == null)
cm = (CurrencyManager)this.BindingContext [dtTables];
cm.PositionChanged += new EventHandler(this.cm_PositionChanged );
int r = cm.Position;
String strTable = dtTables.Rows[r]["TABLE_NAME"].ToString ();
cn = new OleDbConnection(strCn);
cn.Open();
dtColumns = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,new Object[]{null,null, strTable, null});
dvColumns = new DataView(dtColumns);
dvColumns.Sort = "ORDINAL_POSITION";
dataGrid2.DataSource = dvColumns;
dataGrid2.ReadOnly = true;
cn.Close();
}
private void cm_PositionChanged( object sender, System.EventArgs e)
{
GetColumnsList();
}
- 插入以下代码进行布局和使用 TableStyles 格式化表 DataGrid 。 请注意以便日期列的非默认格式的 PropertyDescriptor
private void button2_Click(object sender, System.EventArgs e)
{
FormatTablesGrid(dtTables);
}
private void FormatTablesGrid(DataTable dt2format)
{
DataGridTableStyle gs = new DataGridTableStyle();
gs.MappingName = dt2format.TableName;
DataGridColumnStyle cs = new DataGridTextBoxColumn();
cs.MappingName = "TABLE_NAME";
cs.HeaderText = "Table Name";
cs.Width = 75;
gs.GridColumnStyles.Add(cs);
cs = new DataGridTextBoxColumn();
cs.MappingName = "TABLE_TYPE";
cs.HeaderText = "Table Type";
cs.Width = 75;
gs.GridColumnStyles.Add(cs);
CurrencyManager cm = (CurrencyManager)this.BindingContext[dt2format];
PropertyDescriptor pd = cm.GetItemProperties()["DATE_CREATED"];
cs = new DataGridTextBoxColumn(pd, "d");
cs.MappingName = "DATE_CREATED";
cs.HeaderText = "Date Created";
cs.Width = 75;
gs.GridColumnStyles.Add(cs);
cm = ( CurrencyManager)this.BindingContext[dt2format];
pd = cm.GetItemProperties()["DATE_MODIFIED"];
cs = new DataGridTextBoxColumn(pd, "d");
cs.MappingName = "DATE_MODIFIED";
cs.HeaderText = "Date Modified";
cs.Width = 75;
gs.GridColumnStyles.Add(cs);
dataGrid1.TableStyles.Add(gs);
button2.Enabled = false;
}
- 插入布局和使用 TableStyle 格式化列 DataGrid 以下代码:
private void button3_Click(object sender, System.EventArgs e)
{
FormatColumnsGrid(dtTables);
}
private void FormatColumnsGrid(DataTable dt2format)
{
DataGridTableStyle gs = new DataGridTableStyle();
gs.MappingName = dtColumns.TableName;
DataGridColumnStyle cs = new DataGridTextBoxColumn();
cs.MappingName = "COLUMN_NAME";
cs.HeaderText = "Column Name";
cs.Width = 100;
gs.GridColumnStyles.Add(cs);
cs = new DataGridTextBoxColumn();
cs.MappingName = "ORDINAL_POSITION";
cs.HeaderText = "Ordinal Position";
cs.Width = 100;
gs.GridColumnStyles.Add(cs);
cs = new DataGridTextBoxColumn();
cs.MappingName = "DATA_TYPE";
cs.HeaderText = "Data Type";
cs.Width = 75;
gs.GridColumnStyles.Add(cs);
cs = new DataGridTextBoxColumn();
cs.MappingName = "CHARACTER_MAXIMUM_LENGTH";
cs.HeaderText = "Text Length";
cs.Width = 75;
gs.GridColumnStyles.Add(cs);
cs = new DataGridTextBoxColumn();
cs.MappingName = "NUMERIC_PRECISION";
cs.HeaderText = "Numeric Precision";
cs.Width = 75;
gs.GridColumnStyles.Add(cs);
dataGrid2.TableStyles.Add(gs);
button3.Enabled = false;
}
- 运行该项目。
- 单击 检索元数据 (Button 1)。
表 列表 (DataGrid 1) 填充的 GetOleDbSchemaTable 方法为 Excel 工作簿中的每个表返回信息的所有列。 列 列表 (DataGrid2) 填充在同一时间与为 表 列表中第一个表格列返回的信息的所有列。 - 从 表 列表中选择一个不同的表。
列列表显示从 cm_PositionChanged 事件处理程序的结果所选表列。 - 单击 表的列表 (Button 2)。 此定义并应用了一个 TableMappingStyle 到 DataGrid 1,进行更加友好的列标题,并显示只有用的数据的四个列
TABLE _ NAME
TABLE _ TYPE
DATE_CREATED
DATE
而不是由 GetOleDbSchemaTable 方法返回九个列。
空白列未显示的是: TABLE _ CATALOG
TABLE _ SCHEMA
TABLE_GUID
说明
TABLE _ PROPID
- 单击 列的列表 (Button 3)。 此定义,并应用一个 TableMappingStyle 到 DataGrid2,进行更加友好的列标题,并显示仅五个最有用的列 COLUMN _ NAME ORDINAL_POSITION DATA_TYPE MAXIMUM_CHARACTER_LENGTH NUMERIC_PRECISION 28 个列中返回的 GetOleDbSchemaTable 方法数据。
未显示的列是:
TABLE _ CATALOG
TABLE _ SCHEMA
TABLE _ NAME (已称为)
COLUMN_GUID
COLUMN_PROPID
COLUMN_HASDEFAULT (始终 False)
COLUMN_DEFAULT
COLUMN_FLAGS
IS_NULLABLE (始终 True)
TYPE_GUID
CHARACTER_OCTET_LENGTH
NUMERIC_SCALE
DATETIME_PRECISION
CHARACTER_SET_CATALOG
CHARACTER_SET_SCHEMA
CHARACTER_SET_NAME
COLLATION_CATALOG
COLLATION_SCHEMA
COLLATION_NAME
DOMAIN_CATALOG
DOMAIN_SCHEMA
DOMAIN _ NAME
说明
- 单击在 DataGrid 1 选择不同的表中的其他行。 自动更新列列表。 先前应用到每个 DataGrid TableStyles 保持有效。
疑难解答
- 对 Excel 数据源的 GetOleDbSchemaTable 方法返回的列数据类型不是在所有情况下,为在早期版本的 ADO OpenSchema 方法返回的数据类型相同的:
收起该表格展开该表格
| 列类型 | 经典 ADO | ADO.Net (OleDb) |
|---|
| 数字 | 5 adDouble | 5 OleDbType.Double |
| 货币 | 6 adCurrency | 6 OleDbType.Currency |
| 日期 / 时间 | 7 adDate | 7 OleDbType.Date |
| 布尔值 | 11 adBoolean | 11 OleDbType.Boolean |
| 文本 < 255 个 | 202 adVarWChar | 130 OleDbType.WChar |
| 备注 | 203 adLongVarWChar | 130 OleDbType.WChar |
- GetOleDbSchemaTable ,类似于 OpenSchema ,从空白 Excel 工作表中返回一列 ("F 1"),实际上,数据或列的标题时存在。
有关其他信息,单击下面,文章编号,以查看 Microsoft 知识库中相应:
257819?
(http://support.microsoft.com/kb/257819/EN-US/
)
如何使用 ADO 来处理来自 Visual Basic 或 VBA 的 Excel 数据