如何在不指定工作表名称的情况下dynamic读取工作表

Dim MyConnection As System.Data.OleDb.OleDbConnection Dim DtSet As System.Data.DataSet Dim MyCommand As System.Data.OleDb.OleDbDataAdapter Dim filePath = GlobalVariable.savedPath + GlobalVariable.excelFileName 'Code to Use an Oledb Connection to get data from the Excel File MyConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filePath & ";Extended Properties='Excel 12.0 Xml;HDR=YES;';") 'Code to Read the Sheet Selected from the Excel Spread Sheet' MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection) '-- Extra Code Not Needed which Maps the tables as Columns from the Spreadsheet 'MyCommand.TableMappings.Add("Table", "Net-informations.com") DtSet = New System.Data.DataSet MyCommand.Fill(DtSet) 'Populates GridView with the excel Spreadsheet GridView1.DataSource = DtSet.Tables(0) 'Code Below needed to show the excel to GridView GridView1.DataBind() MyConnection.Close() 

这段代码基本上显示了网格视图中使用select * from Sheet1$的excel文件。 但是,我想要在数据源中有任何文件来dynamic显示Excel工作表。

以下将通过OleDb从一个特定的Excel文件中收集表格名称,不幸的是,在读取表格时sortingaz,而不像Excel自动化,您可以通过序号位置收集表格名称。

接下来,我相信你知道,但无论如何要说,一张表的第一行可以是列名或数据,并依赖于它是连接string需要设置为正确的一个(如代码中所示),但没有真正的方法来确定这一点,通常是“你知道吗”或“顾客决定”。

首先,支持类(从这个代码示例中获取 )

 Imports System.Data.OleDb Public Class Connections Public Sub New() End Sub ''' <summary> ''' Create a connection where first row contains column names ''' </summary> ''' <param name="FileName"></param> ''' <param name="IMEX"></param> ''' <returns></returns> ''' <remarks></remarks> <System.Diagnostics.DebuggerStepThrough()> _ Public Function HeaderConnectionString(ByVal FileName As String, Optional ByVal IMEX As Integer = 1) As String Dim Builder As New OleDbConnectionStringBuilder If IO.Path.GetExtension(FileName).ToUpper = ".XLS" Then Builder.Provider = "Microsoft.Jet.OLEDB.4.0" Builder.Add("Extended Properties", String.Format("Excel 8.0;IMEX={0};HDR=Yes;", IMEX)) Else Builder.Provider = "Microsoft.ACE.OLEDB.12.0" Builder.Add("Extended Properties", String.Format("Excel 12.0;IMEX={0};HDR=Yes;", IMEX)) End If Builder.DataSource = FileName Return Builder.ToString End Function ''' <summary> ''' Create a connection where first row contains data ''' </summary> ''' <param name="FileName"></param> ''' <param name="IMEX"></param> ''' <returns></returns> ''' <remarks></remarks> <System.Diagnostics.DebuggerStepThrough()> _ Public Function NoHeaderConnectionString(ByVal FileName As String, Optional ByVal IMEX As Integer = 1) As String Dim Builder As New OleDbConnectionStringBuilder If IO.Path.GetExtension(FileName).ToUpper = ".XLS" Then Builder.Provider = "Microsoft.Jet.OLEDB.4.0" Builder.Add("Extended Properties", String.Format("Excel 8.0;IMEX={0};HDR=No;", IMEX)) Else Builder.Provider = "Microsoft.ACE.OLEDB.12.0" Builder.Add("Extended Properties", String.Format("Excel 12.0;IMEX={0};HDR=No;", IMEX)) End If Builder.DataSource = FileName Return Builder.ToString End Function End Class 

另一个支持类

 Imports System.Data.OleDb Public Class Utility Public Sub New() End Sub ''' <summary> ''' Returns a list of sheet names from Excel or table names from Access ''' </summary> ''' <param name="ConnectionString"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function SheetNames(ByVal ConnectionString As String) As List(Of SheetNameData) Dim Names As New List(Of SheetNameData) Using cn As New OleDbConnection(ConnectionString) cn.Open() Dim dt As DataTable = New DataTable With {.TableName = "AvailableSheetsTables"} dt = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"}) cn.Close() Names = ( From F In dt.Rows.Cast(Of DataRow)() Select New SheetNameData With { .DisplayName = F.Field(Of String)("TABLE_NAME").Replace("$", ""), .ActualName = F.Field(Of String)("TABLE_NAME") } ).ToList End Using Return Names End Function End Class Public Class SheetNameData Public Sub New() End Sub Public Property DisplayName As String Public Property ActualName As String End Class 

首先你要注意的是文件名和path是硬编码的,没有检查,看看它是否存在,因为这整个回复是一个样本,一直到手边的任务。 在button单击事件我们得到表名称,这当然可以在另一个事件,例如表单加载完成。 工作表名称被放入一个强types列表中,第一个工作表被选中(如果不确定是否有工作表,那么断言将被使用)。 我打开第一行作为数据的工作表,如果你的列标题,我也包括一个连接方法。 一个DataTable加载使用的行和列,DataTable成为DataGridView的DataSource。

 Public Class Form1 Private FileName As String = IO.Path.Combine( AppDomain.CurrentDomain.BaseDirectory, "PeopleData.xlsx") Private Connection As Connections = New Connections Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim Utils = New Utility Dim SheetsList As List(Of SheetNameData) = Utils.SheetNames( Connection.NoHeaderConnectionString(IO.Path.GetFileName(FileName))) Dim dt As New DataTable Dim ConnectionString As String = Connection.NoHeaderConnectionString(FileName) Using cn As New OleDb.OleDbConnection With {.ConnectionString = ConnectionString} Using cmd As New OleDb.OleDbCommand( String.Format("SELECT * FROM [{0}]", SheetsList.FirstOrDefault.ActualName), cn) cn.Open() dt.Load(cmd.ExecuteReader) End Using End Using DataGridView1.DataSource = dt End Sub End Class 

结束时请注意,如果你想要一个特定的表格,而不是随机的表格,你必须打开每张表格,检查预期的数据,例如,如果第一行有字段/列名称读取第一行,并用无连接string那么一旦find正确的表单,使用带有标题集的连接string加载它。

希望这可以帮助 :-)