使用OleDB范围错误从Excel 2013文件中读取非常大的数据

时间:2016-01-11 06:59:48

标签: sql vb.net excel oledb

我试图在OleDB的帮助下使用Visual Basic.NET读取Excel 2013文件(.xlsx大小约为100 MB)。主要关注的是在行中获得系统内存异常:

da.Fill(dt)

来自下面的代码。

Private Function ReadExcelFile() As DataSet
    Dim ds As New DataSet()

    Dim connectionString As String =
    "Provider=Microsoft.ACE.OLEDB.12.0;;Extended Properties=Excel 12.0 XML;Data Source=C:\file.xlsx;"

    Using connection As New OleDbConnection(connectionString)
        connection.Open()
        Dim cmd As New OleDbCommand()
        cmd.Connection = connection
        Dim dtSheet As DataTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)

        For Each dr As DataRow In dtSheet.Rows
            Dim sheetName As String = dr("TABLE_NAME").ToString()
            If Not sheetName.EndsWith("$") Then
                Continue For
            End If

            cmd.CommandText = "SELECT * FROM [" & sheetName & "];"
            Dim dt As New DataTable()
            dt.TableName = sheetName
            Dim da As New OleDbDataAdapter(cmd)
            da.Fill(dt)
            ds.Tables.Add(dt)
        Next

        cmd = Nothing
        connection.Close()
    End Using
    Return ds
End Function

但我认为最好的解决方案是按块读取数据,所以我发现我可以通过在SQL语句中添加列范围来读取数据,如下所示:

 cmd.CommandText = "SELECT * FROM [" & sheetName & "B1:B10];"

我通过在该范围内进行增量来进行循环但是我发现了一个错误。以此为例,

cmd.CommandText = "SELECT * FROM [" & sheetName & "B50000:B51000];"

它仍然有效。但是,如果我这样做,

cmd.CommandText = "SELECT * FROM [" & sheetName & "B70000:B70001];"

我收到此错误。

OleDb Error

请注意,Excel文件有475128行,B70000-B70001甚至不是总数的一半。

Total Columns

有人可以解决一些问题吗?我想我在这里遗漏了一些东西。

1 个答案:

答案 0 :(得分:1)

我找到了一个有效的解决方案。而不是使用DataSet,使用DataReader。我可以添加一个工人,这样它就不会挂断。

 Private Function ReadExcelFile() As DataSet
    Dim ds As New DataSet()

    Dim connectionString As String = GetConnectionString()

    Using connection As New OleDbConnection(connectionString)
        connection.Open()
        Dim cmd As New OleDbCommand()
        cmd.Connection = connection
        Dim dtSheet As DataTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)

        For Each dr As DataRow In dtSheet.Rows
            Dim sheetName As String = dr("TABLE_NAME").ToString()
            If Not sheetName.EndsWith("$") Then
                Continue For
            End If
            cmd.CommandText = "SELECT * FROM [" & sheetName & "];"
            Dim ddr As OleDbDataReader = cmd.ExecuteReader()
            Dim counter As Integer = 0
            While (ddr.Read())
                MessageBox.Show(ddr.GetValue(0))
            End While
        Next
        cmd = Nothing
        connection.Close()
    End Using
    Return ds
End Function

行:

Dim ddr As OleDbDataReader = cmd.ExecuteReader()
Dim counter As Integer = 0
While (ddr.Read())
     MessageBox.Show(ddr.GetValue(0))
End While

是可以访问第一列(索引0)的行的基本代码。这是有效的,因为我读到DataSet是一个内存中的对象(这就是我们可能使系统内存异常的原因) - Check here for reference

我仍然想知道为什么我的上述问题突然爆发。