I am working with some code that uses an OleDbConnection to load data from an Excel file to a DataTable. Currently it defaults to the first Sheet but getting it's name using the following code:
string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=myFilename.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES"""
DataTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (schemaTable.Rows.Count > 0)
return schemaTable.Rows[0]["TABLE_NAME"].ToString();
else
return "Sheet1$"
This has been working fine until recently when the Excel document (we are receiving from a third party) star开发者_如何学JAVAted containing named Ranges. I'm there are no hidden sheets that I can find.
Now
schemaTable.Rows[0]["TABLE_NAME"].ToString()
returns the name of the first Range.
Is there something different I can do with my schemaTable object to identity just the sheets and not the named Ranges in the sheet?
Is the use of OleDbConnection mandatory or you can switch to other options (DAO for instance) ?
alternative solution 1 : using interop :
Private Function GetSheetNames(ByVal path As String)
Dim lst As New List(Of String)
'Note: this will not work for Excel 2007 (.xlsx) workbooks.
If IO.File.Exists(path) AndAlso IO.Path.GetExtension(path) = ".xls" Then
Dim app As New Excel.Application
Dim WB As Excel.Workbook
Try
WB = app.Workbooks.Open(Filename:=path)
If WB IsNot Nothing Then
For Each ws As Excel.Worksheet In WB.Sheets
lst.Add(ws.Name)
Next
WB.Close()
System.Runtime.InteropServices.Marshal.ReleaseComObject(WB)
WB = Nothing
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
System.Runtime.InteropServices.Marshal.ReleaseComObject(app)
app = Nothing
End Try
End If
Return lst
End Function
Source : http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/21d3f77c-1d3d-44e0-9bd5-eca45a0affa6
Alternative solution 2 : using DAO :
Dim dao_dbE As dao.DBEngine
Dim dao_DB As dao.Database
dao_dbE = New dao.DBEngine
Dim sheetsNames As List(Of String) = New List(Of String)()
dao_DB = dao_dbE.OpenDatabase(completeFileName, False, True, "Excel 8.0;")
For i As Integer = 0 To dao_DB.TableDefs.Count - 1
sheetsNames.Add(dao_DB.TableDefs(i).Name)
Next
As @Heinzi correctly sad you should investigate other properties of returned metadata, it's the only way. Most probably ranges will be different from sheets by some property value.
Update:
Since this solution doesn't work, and if file is in XSLX format, I think fastest and simpliest solution is just to drill down to raw xml (remember XLSX is just ZIP) myFilename.xlsx/xl/workbook.xml
using, say, #ZipLib and grab all sheets names from <sheets>
node.
精彩评论