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

我在这里有一个有趣的难题,我如何快速(不到1分钟)将大数据表(从SQL填充,35,000行)导出到用户的Excel电子表格中。 我有代码可以处理导出,虽然代码本身没有什么是“错误的”,它是非常慢,需要4分钟导出整个文件(有时如果用户有更less的内存或更多的运行他们的系统)。 可悲的是,这是使用我们以前的方法所用的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 

就像使用VBA来自动化Excel一样,您可以直接将一个数组赋值给一个Range对象的值:这是作为一个单独的操作完成的,因此您可以删除在.Net代码和Excel实例。

例如,请参阅这里接受的答案: 将数组写入Excel范围

这里是我自己的一段代码,它执行从DataTable到Excel工作表的非常快的数据导出(使用“Stopwatch”对象来比较速度并给我一个评论):

 Dim _excel As New Excel.Application Dim wBook As Excel.Workbook Dim wSheet As Excel.Worksheet wBook = _excel.Workbooks.Add() wSheet = wBook.ActiveSheet() Dim dc As System.Data.DataColumn Dim colIndex As Integer = 0 Dim rowIndex As Integer = 0 'Nombre de mesures Dim Nbligne As Integer = DtMesures.Rows.Count 'Ecriture des entêtes de colonne et des mesures '(Write column headers and data) For Each dc In DtMesures.Columns colIndex = colIndex + 1 'Entête de colonnes (column headers) wSheet.Cells(1, colIndex) = dc.ColumnName 'Données(data) 'You can use CDbl instead of Cobj If your data is of type Double wSheet.Cells(2, colIndex).Resize(Nbligne, ).Value = _excel.Application.transpose(DtMesures.Rows.OfType(Of DataRow)().[Select](Function(k) CObj(k(dc.ColumnName))).ToArray()) Next 

我们有一个VB.NET的应用程序,正是这样做,并花了更多的时间,我们的用户在慢PC上…有时15分钟。

该应用程序现在是一个ASP / VB.NET应用程序,它只是build立一个HTML表格,并将结果输出为.xls扩展名… excel能够读取HTML表格并将其parsing为网格格式。 您仍然可以传递XML格式和选项,水平面板locking等。

如果你没有使用ASP.NET的选项…尝试寻找一种方法来build立一个HTML表格string,并有Excelparsing&填充你…更快! 我敢肯定,Excel也可以parsing其他types…. XML,数组,HTML等…都将比通过VB.NET对象手动构build每一行更快。