使用OleDbConnection将行插入现有Excel工作表

时间:2014-07-18 14:09:52

标签: oledb export-to-excel

我正在根据数据列表和选项卡名称构建插入语句。我有4个选项卡,最后2个获取数据成功插入,前2个没有。

我注释掉了插入所有标签但只有一个。 excel文件的大小增加,但行仍为空白。有什么想法吗?

编辑:出于某种原因,我用作“空白模板”的Excel文件在前两页的行中具有“空”值。第一个在前100K行中有“空值”,秒在前700行中有空值。在这些行之后插入数据,这解释了文件大小增加的原因。现在我尝试插入时“操作必须使用可更新的查询”。

Public Sub BuildReport(Of T)(tabName As String, dataList As IEnumerable(Of T))
    '// Setup the connectionstring for Excel 2007+ XML format
    '// http://www.connectionstrings.com/ace-oledb-12-0/ 

    If ((tabName.EndsWith("$") = True AndAlso m_TabList.Contains(tabName) = False) OrElse m_TabList.Contains(tabName & "$") = False) Then
        Throw New Exception(String.Format("The specified tab does not exist in the Excel spreadsheet: {0}", tabName))
    End If

    Using excelConn As New OleDbConnection(m_ConnectionString)

        excelConn.Open()

        Dim insertStatementList As IEnumerable(Of String) = BuildInsertStatement(Of T)(tabName, dataList)

        Using excelCommand As New OleDbCommand()
            excelCommand.CommandType = CommandType.Text
            excelCommand.Connection = excelConn

            For Each insertStatement In insertStatementList
                excelCommand.CommandText = insertStatement
                excelCommand.ExecuteNonQuery()
            Next

        End Using

    End Using

End Sub

Private Function BuildInsertStatement(Of T)(tabName As String, dataList As IEnumerable(Of T)) As IEnumerable(Of String)

    Dim insertStatementList As New List(Of String)

    Dim insertStatement As New StringBuilder()

    For Each dataItem As T In dataList
        Dim props As PropertyInfo() = GetType(T).GetProperties()
        insertStatement.Clear()
        insertStatement.AppendFormat("INSERT INTO [{0}$] ", tabName)

        Dim nameValueDictionary As New Dictionary(Of String, String)

        For Each prop As PropertyInfo In props
            Dim excelColumn As ExcelColumnAttribute = CType(prop.GetCustomAttributes(GetType(ExcelColumnAttribute), False).FirstOrDefault(), ExcelColumnAttribute)

            If (excelColumn IsNot Nothing) Then
                Dim value As Object = prop.GetValue(dataItem, Nothing)
                If (value IsNot Nothing AndAlso value.GetType() <> GetType(Integer) _
                    AndAlso value.GetType() <> GetType(Double) _
                    AndAlso value.GetType() <> GetType(Decimal) _
                    AndAlso value.GetType() <> GetType(Boolean)) Then
                    value = String.Format("""{0}""", value)
                ElseIf (value Is Nothing) Then
                    value = "NULL"
                End If
                nameValueDictionary.Add(excelColumn.ColumnName, value)
            End If
        Next

        Dim columList As String = String.Join(",", nameValueDictionary.Keys)
        Dim valueList As String = String.Join(",", nameValueDictionary.Select(Function(x) x.Value))

        insertStatement.AppendFormat("({0}) ", columList)
        insertStatement.AppendFormat("VALUES ({0})", valueList)

        insertStatementList.Add(insertStatement.ToString())

    Next

    Return insertStatementList

End Function

1 个答案:

答案 0 :(得分:0)

出于某种原因,我用作“空白模板”的Excel文件在前两张纸的行中具有“空”值。第一个在前100K行中有“空值”,第二个在前700行中有空值。在这些行之后插入数据,这解释了文件大小增加的原因。现在,我试图插入时“操作必须使用可更新的查询”。

我在这里找到了第二个问题的答案:Operation must use an updateable query when updating excel sheet

只需要从我尝试解决问题时添加的连接字符串的扩展属性中删除“IMEX = 1”。