无法使用 GetOleSchemaTable() 获取工作表名称

发布于 2024-11-15 11:13:24 字数 669 浏览 17 评论 0原文

我正在处理一些使用 OleDbConnection 将数据从 Excel 文件加载到 DataTable 的代码。目前它默认为第一个工作表,但使用以下代码获取它的名称:

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$"

直到最近 Excel 文档(我们从第三方接收)开始包含命名范围时,它一直工作正常。我找不到任何隐藏的床单。

现在

schemaTable.Rows[0]["TABLE_NAME"].ToString()

返回第一个范围的名称。

我可以对 schemaTable 对象做一些不同的事情来仅标识工作表而不是工作表中的命名范围吗?

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) started 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心的憧憬 2024-11-22 11:13:24

是否必须使用 OleDbConnection 或者您可以切换到其他选项(例如 DAO)?

替代解决方案 1:使用互操作:

    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

来源:http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/21d3f77c-1d3d-44e0-9bd5-eca45a0affa6

替代解决方案 2:使用 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

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
面犯桃花 2024-11-22 11:13:24

正如@Heinzi 所悲伤的那样,您应该调查返回元数据的其他属性,这是唯一的方法。最有可能的范围将与工作表在某些属性值上有所不同。

更新:
由于此解决方案不起作用,并且如果文件采用 XSLX 格式,我认为最快、最简单的解决方案就是深入到原始 xml(记住 XLSX 只是 ZIP)myFilename.xlsx/xl/workbook.xml< /code> 使用 #ZipLib 并从中获取所有工作表名称 节点。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文