在 VB.Net 中将大数据表快速导出到 Excel 电子表格

2023-12-13

我这里有一个有趣的难题,如何快速(在 1 分钟内)将大型数据表(由 SQL 填充,35,000 行)导出到 Excel 电子表格中供用户使用。我有可以处理导出的代码,虽然代码本身没有任何“错误”,但导出整个文件需要 4 分钟,速度慢得令人发指(如果用户的 RAM 较少或运行的内存较多,有时会需要更长的时间)他们的系统)。遗憾的是,与使用我们的旧方法花费 10 多分钟相比,这已经有所改进。简而言之,在不使用第三方组件的情况下,是否可以做得更快?如果是这样,怎么办?我的代码如下,速度减慢发生在每行写入的消息框 6 和 7 之间。感谢大家抽出宝贵的时间来查看此内容:

    Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnJeffTest.Click
           Test(MySPtoExport)
    End Sub

Private Sub Test(ByVal SQL As String)
    'Declare variables used to execute the VUE Export stored procedure
    MsgBox("start stop watch")
    Dim ConnectionString As New SqlConnection(CType(ConfigurationManager.AppSettings("ConnString"), String))
    Dim cmdSP As New SqlClient.SqlCommand
    Dim MyParam As New SqlClient.SqlParameter
    Dim MyDataAdapter As New SqlClient.SqlDataAdapter
    Dim ExportDataSet As New DataTable
    Dim FilePath As String

    MsgBox("stop 1 - end of declare")

    Try

        ' open the connection
        ConnectionString.Open()

        ' Use the connection for this sql command
        cmdSP.Connection = ConnectionString

        'set this command as a stored procedure command
        cmdSP.CommandType = CommandType.StoredProcedure

        'get the stored procedure name and plug it in
        cmdSP.CommandText = SQL

        'Add the Start Date parameter if required
        Select Case StDt
            Case Nothing
                ' there's no parameter to add
            Case Is = 0
                ' there's no parameter to add
            Case Else
                'add the parameter name, it's direction and its value
                MyParam = cmdSP.Parameters.Add("@StartDate", SqlDbType.VarChar)
                MyParam.Direction = ParameterDirection.Input
                MyParam.Value = Me.txtStartDate.Text
        End Select
        MsgBox("stop 2 - sql ready")
        'Add the End Date parameter if required
        Select Case EdDt
            Case Nothing
                ' there's no parameter to add
            Case Is = 0
                ' there's no parameter to add
            Case Else
                'add the parameter name, it's direction and its value

                MyParam = cmdSP.Parameters.Add("@EndDate", SqlDbType.VarChar)
                MyParam.Direction = ParameterDirection.Input
                MyParam.Value = Me.txtEndDate.Text
        End Select

        'Add the single parameter 1 parameter if required
        Select Case SPar1
            Case Is = Nothing
                ' there's no parameter to add
            Case Is = ""
                ' there's no parameter to add
            Case Else
                'add the parameter name, it's direction and its value
                MyParam = cmdSP.Parameters.Add(SPar1, SqlDbType.VarChar)
                MyParam.Direction = ParameterDirection.Input
                MyParam.Value = Me.txtSingleReportCrt1.Text
        End Select

        'Add the single parameter 2 parameter if required
        Select Case Spar2
            Case Is = Nothing
                ' there's no parameter to add
            Case Is = ""
                ' there's no parameter to add
            Case Else
                'add the parameter name, it's direction and its value
                MyParam = cmdSP.Parameters.Add(Spar2, SqlDbType.VarChar)
                MyParam.Direction = ParameterDirection.Input
                MyParam.Value = Me.txtSingleReportCrt2.Text
        End Select

        MsgBox("stop 3 - params ready")

        'Prepare the data adapter with the selected command 
        MyDataAdapter.SelectCommand = cmdSP

        ' Set the accept changes during fill to false for the NYPDA export
        MyDataAdapter.AcceptChangesDuringFill = False

        'Fill the Dataset tables (Table 0 = Exam Eligibilities, Table 1  = Candidates Demographics)
        MyDataAdapter.Fill(ExportDataSet)

        'Close the connection
        ConnectionString.Close()

        'refresh the destination path in case they changed it
        SPDestination = txtPDFDestination.Text

        MsgBox("stop 4 - procedure ran, datatable filled")

        Select Case ExcelFile
            Case True

                FilePath = SPDestination & lblReportName.Text & ".xls"

                Dim _excel As New Microsoft.Office.Interop.Excel.Application
                Dim wBook As Microsoft.Office.Interop.Excel.Workbook
                Dim wSheet As Microsoft.Office.Interop.Excel.Worksheet

                wBook = _excel.Workbooks.Add()
                wSheet = wBook.ActiveSheet()

                Dim dt As System.Data.DataTable = ExportDataSet
                Dim dc As System.Data.DataColumn
                Dim dr As System.Data.DataRow
                Dim colIndex As Integer = 0
                Dim rowIndex As Integer = 0

                MsgBox("stop 5 - excel stuff declared")

                For Each dc In dt.Columns
                    colIndex = colIndex + 1
                    _excel.Cells(1, colIndex) = dc.ColumnName
                Next

                MsgBox("stop 6 - Header written")

                For Each dr In dt.Rows
                    rowIndex = rowIndex + 1
                    colIndex = 0
                    For Each dc In dt.Columns
                        colIndex = colIndex + 1
                        _excel.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName)
                    Next
                Next

                MsgBox("stop 7 - rows written")

                wSheet.Columns.AutoFit()

                MsgBox("stop 8 - autofit complete")

                Dim strFileName = SPDestination & lblReportName.Text & ".xls"

                If System.IO.File.Exists(strFileName) Then
                    System.IO.File.Delete(strFileName)
                End If

                MsgBox("stop 9 - file checked")

                wBook.SaveAs(strFileName)
                wBook.Close()
                _excel.Quit()
        End Select

        MsgBox("File " & lblReportName.Text & " Exported Successfully!")


        'Dispose of unneeded objects
        MyDataAdapter.Dispose()
        ExportDataSet.Dispose()
        StDt = Nothing
        EdDt = Nothing
        SPar1 = Nothing
        Spar2 = Nothing
        MyParam = Nothing
        cmdSP.Dispose()
        cmdSP = Nothing
        MyDataAdapter = Nothing
        ExportDataSet = Nothing

    Catch ex As Exception
        '  Something went terribly wrong.  Warn user.
        MessageBox.Show("Error: " & ex.Message, "Stored Procedure Running Process ", _
       MessageBoxButtons.OK, MessageBoxIcon.Error)

    Finally
        'close the connection in case is still open
        If Not ConnectionString.State = ConnectionState.Closed Then
            ConnectionString.Close()
            ConnectionString = Nothing
        End If

        ' reset the fields
        ResetFields()

    End Try
End Sub

尽管这个问题是几年前提出的,但我想我会添加我的解决方案,因为问题是在 VB 中提出的,而“最佳答案”是在 C# 中。该解决方案在配备 16GB RAM 的 i7 系统上可在 4 秒内写入 22,000 多行 (1.9MB)。


Imports Excel = Microsoft.Office.Interop.Excel

Public Class Main
    Private Sub btnExportToExcel(sender As Object, e As EventArgs) Handles btnExpToExcel.Click
        'Needed for the Excel Workbook/WorkSheet(s)
        Dim app As New Excel.Application
        Dim wb As Excel.Workbook = app.Workbooks.Add()
        Dim ws As Excel.Worksheet
        Dim strFN as String = "MyFileName.xlsx"    'must have ".xlsx" extension

        'Standard code for filling a DataTable from SQL Server
        Dim strSQL As String = "My SQL Statement for the DataTable"
        Dim conn As New SqlConnection With {.ConnectionString = "My Connection"}
        Dim MyTable As New DataTable
        Dim cmd As New SqlCommand(strSQL, conn)
        Dim da As New SqlDataAdapter(cmd)
        da.Fill(MyTable)

        'Add a sheet to the workbook and fill it with data from MyTable
        'You could create multiple tables and add additional sheets in a loop
        ws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
        DataTableToExcel(MyTable, ws, strSym)

        wb.SaveAs(strFN)    'save and close the WorkBook
        wb.Close()

        MsgBox("Export complete.")
    End Sub

    Private Sub DataTableToExcel(dt As DataTable, ws As Excel.Worksheet, TabName As String)
        Dim arr(dt.Rows.Count, dt.Columns.Count) As Object
        Dim r As Int32, c As Int32
        'copy the datatable to an array
        For r = 0 To dt.Rows.Count - 1
            For c = 0 To dt.Columns.Count - 1
                arr(r, c) = dt.Rows(r).Item(c)
            Next
        Next

        ws.Name = TabName   'name the worksheet
        'add the column headers starting in A1
        c = 0
        For Each column As DataColumn In dt.Columns
            ws.Cells(1, c + 1) = column.ColumnName
            c += 1
        Next
        'add the data starting in cell A2
        ws.Range(ws.Cells(2, 1), ws.Cells(dt.Rows.Count, dt.Columns.Count)).Value = arr
    End Sub
End Class

希望能帮助到你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 VB.Net 中将大数据表快速导出到 Excel 电子表格 的相关文章

  • 使用Excel宏执行命令并关闭cmd窗口

    这是我现在正在尝试的 Sub del BJSFM files Call Shell cmd exe S K cd d C UTAS SA del f s q BJSFM gt nul vbNormalFocus End Sub 问题是命令窗
  • 如何在data.table中使用OR条件连接表

    在 data table 中是否可以使用 OR 条件连接表 例如 library data table X lt data table x c a b c d e f y c 1 1 2 2 3 3 z c 10 11 12 13 14 1
  • 从文件资源管理器打开我的应用程序中的文件

    我在 VB NET 中创建了自己的应用程序 该应用程序将其文档保存到具有自己的自定义扩展名 eds 的文件中 假设我已将文件扩展名与我的应用程序正确关联 那么当我在文件资源管理器中双击该文件时 如何实际处理应用程序中所选文件的处理 我是在
  • 在Excel中过滤后打印可见区域的宏

    我有一个根据过滤表的宏column A价值观 现在我想打印only过滤器后的可见行 但遗憾的是它打印了所有行 包括过滤期间隐藏的顶部和底部行 在我的工作表中 有来自的数据Column A I 但打印区域只能是Columns C I 过滤后的
  • 如果单元格包含 1 个或多个关键字,则更改不同单元格的值

    我有一个列 其中包含一些字符串描述 例如 Bob davids mowing the lawn tipping cows 此外 我将在不同的工作表或列上列出关键字列表 例如工作关键字列表1 davids work 播放关键字列表 mowin
  • 使用 UiPath 循环 Excel 文件中的 URL

    我尝试了几种方法 但不知怎的 它们看起来不干净 我有一个 Excel 格式的 URL 文件 一列中有 400 多个 URL 我希望 UiPath 从该文件中读取并一一浏览这些 URL 我尝试让 导航到 从从 Excel 读取的变量中读取 但
  • R:data.table 与 merge(aggregate()) 性能

    或者更一般地说 它是DT SD by versus merge aggregate 话不多说 这里是数据和示例 set seed 5141 size 1e6 df lt data table a rnorm size b paste0 sa
  • 如何通过VBA代码修复仅在Excel共享模式下发生的运行时错误400

    我真的不知道400错误是什么原因造成的 下面的代码在正常模式下运行得很好 但是一旦我在共享模式下启用 Excel 并尝试使用用户表单 它就会给我 VBA 400 我在这里尝试做的是在向用户显示用户表单后更改形状的文本并禁用其 OnActio
  • 如何在VB.NET中从另一个窗体打开一个窗体?

    我认为这很容易 我没有经常使用 VB NET 我正在尝试通过单击按钮打开一个表单 表单不会显示 并且我收到空异常错误 代码有什么问题吗 Private Sub Button3 Click sender As System Object e
  • 如何使用 pandas.to_excel() 创建 Excel **表格**?

    Need the achieve this programmatically from a dataframe https learn microsoft com en us power bi service admin troublesh
  • 在VB.net中动态添加用户控件

    我在 Vb net Windows 应用程序 中制作了自定义 UserControl 如何将其动态添加到表单中 UserControl 本质上只是另一个类 它继承自 Control 因此您可以使用控件执行各种操作 但除此之外它只是一个类 因
  • SPGridView、数据以及确保数据安全的正确方法

    我正在使用 SPGridView 来呈现一些数据 并启用了效果很好的过滤功能 直到您选择数据中的特定项目进行过滤 有问题的数据项在字符串中包含撇号 例如 这是 richards 的字符串 这会导致后过滤器应用程序页面加载因错误而终止 Syn
  • windows XP中如何设置默认编码?

    我尝试使用 StreamReader 打开文件并设置编码 但我希望它采用默认 Windows 编码 我如何更改我的 Windows 编码 区域和语言选项控制面板项目 高级选项卡 影响整个计算机
  • xlwt 可以在单元格中创建一个包含标题和链接变量的超链接吗?

    例如 如何更改以下行 使 test 为变量 T 且 http google com http google com 是变量L ws write 0 0 xlwt Formula test HYPERLINK http google com
  • 在 Django(Python) 中向用户提供 Excel(xlsx) 文件下载

    我正在尝试使用 Django 创建和提供 Excel 文件 我有一个 jar 文件 它获取参数并根据参数生成 excel 文件 并且它可以正常工作 但是 当我尝试获取生成的文件并将其提供给用户下载时 文件损坏了 它的大小为 0kb 这是我用
  • Yajra DataTable Laravel 中的 Foreach

    我试图在我的数据表中放入一个 foreach 循环 但它不起作用 附 如果我删除 foreach 一切都已经正常了 这里附上我的代码 Product Product query colors Color all return Datatab
  • 这个 if 语句中怎么有太多参数

    My IF下面的声明不断错误射击 指出参数太多 为什么是这样 谁能看出下面的语句有什么错误吗 IF G7 EUR H7 1 15 L7 IF G7 USD H7 1 35 L7 IF G7 AUD H7 1 35 L7 IF G7 CAD
  • Sql批量复制截断小数

    当我使用批量复制将十进制值从 C DataTable 插入 Sql Server 2005 时 值会被截断而不是四舍五入 DataTable 中的数据类型为 Decimal 数据库中的数据类型为Decimal 19 3 数据表中的值为 1
  • 根据其他列中的条件对列中的唯一值求和

    A B 1 Total 1 900 2 Product A 700 3 Product A 700 4 Product B 300
  • VBA全局类变量

    我的障碍是试图让多个子程序识别类变量 当我尝试全局声明它们时 出现编译错误 无效的外部过程 然后 当我运行公共函数或子函数来声明变量时 它们在其他子函数中保持未定义状态 我希望多个子程序能够识别变量 因为它们的值应该通过用户窗体进行更改 然

随机推荐