目前我有一个包含1500行和9列的excel文件。每次加载winform时,我都希望excel文件中的记录加载到datagridview中。我正在使用Microsoft office interop将记录导入datagridview,但速度太慢了。
所以我的问题是,我还有什么方法可以加快这个过程?我该怎么办?
Dim xlApp As Microsoft.Office.Interop.Excel.Application
Dim xlWorkBook As Microsoft.Office.Interop.Excel.Workbook
Dim xlWorkSheet As Microsoft.Office.Interop.Excel.Worksheet
xlApp = New Microsoft.Office.Interop.Excel.Application
xlWorkBook = xlApp.Workbooks.Open("C:\Install\Data.xlsx")
xlWorkSheet = xlWorkBook.Sheets("sheet1")
Dim countRows As Integer = xlWorkSheet.UsedRange.Rows.Count()
For i As Integer = 2 To countRows
newVersionRow = VersionDBDataSet.IEVersion.NewIEVersionRow()
newVersionRow.PC_Name = xlWorkSheet.Cells(i, 1).value.ToString()
newVersionRow.PC_Status = xlWorkSheet.Cells(i, 2).value.ToString()
newVersionRow.svcKBNumber = xlWorkSheet.Cells(i, 3).value.ToString()
newVersionRow.svcVersion = xlWorkSheet.Cells(i, 4).value.ToString()
newVersionRow.Last_Updated = DateTime.Parse(xlWorkSheet.Cells(i, 5).value.ToString())
newVersionRow.Patches = Integer.Parse(xlWorkSheet.Cells(i, 6).value)
newVersionRow.Uptime = Integer.Parse(xlWorkSheet.Cells(i, 7).value)
newVersionRow.Count = Integer.Parse(xlWorkSheet.Cells(i, 8).value)
newVersionRow.Offline = Integer.Parse(xlWorkSheet.Cells(i, 9).value)
VersionDBDataSet.IEVersion.Rows.Add(newVersionRow)
If newVersionRow.PC_Status = "Online" Then
numofOnline += 1
lblOnlinePC.Text = numofOnline
Else
numofOffline += 1
lblOfflinePC.Text = numofOffline
End If
Next
xlWorkBook.Close()
xlApp.Quit()
releaseObject(xlApp)
releaseObject(xlWorkBook)
releaseObject(xlWorkSheet)
答案 0 :(得分:1)
一种可能的方法是将所有使用过的单元格读入数组,迭代数组并将单元格数据放入DataTable的行中。以下设置为读取三列数据,如果工作表中有更多列,我们在此演示中忽略它们。因此,为您创建九个数据列并使用相同的逻辑。
注意函数HasHeader的最后一个参数如果传递为True,则数组中的第一行将被视为列名,传递False则表示第一行中的数据。有了这个说代码假设我们很可能从第一行开始,但即便如此,如果我们从第4行开始并且第4行有列标题,这可能是一个问题,因为上面的行也被收集并且会甩开因此,这里的魔力可能不适合你。
编辑:刚看到您使用代码更新了您的问题,以下内容可能无法接受,因为看起来您不是从第一行开始,但您可以跳过数组中的前几个元素得到你想要的东西。
示例用法
Dim fileName As String = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Customers.xlsx")
Dim sheetName As String = "Customers"
Dim dtCustomers As DataTable = UsedRowsToDataTable(fileName, sheetName, True)
DataGridView1.DataSource = dtCustomers
将数据读入DataTable的代码
Option Strict On
Option Infer Off
Imports Excel = Microsoft.Office.Interop.Excel
Imports Microsoft.Office
Imports System.Runtime.InteropServices
Module ExcelIterataingData_DataTable
Public Function UsedRowsToDataTable(
ByVal FileName As String,
ByVal SheetName As String,
ByVal HasHeader As Boolean) As DataTable
Dim dtSheetData As New DataTable
If IO.File.Exists(FileName) Then
Dim Proceed As Boolean = False
Dim xlApp As Excel.Application = Nothing
Dim xlWorkBooks As Excel.Workbooks = Nothing
Dim xlWorkBook As Excel.Workbook = Nothing
Dim xlWorkSheet As Excel.Worksheet = Nothing
Dim xlWorkSheets As Excel.Sheets = Nothing
Dim xlCells As Excel.Range = Nothing
xlApp = New Excel.Application
xlApp.DisplayAlerts = False
xlWorkBooks = xlApp.Workbooks
xlWorkBook = xlWorkBooks.Open(FileName)
xlApp.Visible = False
xlWorkSheets = xlWorkBook.Sheets
For x As Integer = 1 To xlWorkSheets.Count
xlWorkSheet = CType(xlWorkSheets(x), Excel.Worksheet)
If xlWorkSheet.Name = SheetName Then
Proceed = True
Exit For
End If
Marshal.FinalReleaseComObject(xlWorkSheet)
xlWorkSheet = Nothing
Next
If Proceed Then
dtSheetData.Columns.AddRange(
New DataColumn() _
{
New DataColumn With
{
.ColumnName = "CompanyName",
.DataType = GetType(String)
},
New DataColumn With
{
.ColumnName = "ContactName",
.DataType = GetType(String)
},
New DataColumn With
{
.ColumnName = "ContactTitle",
.DataType = GetType(String)
}
}
)
Dim xlUsedRange As Excel.Range = xlWorkSheet.UsedRange
Try
Dim ExcelCells(,) As Object =
CType(xlUsedRange.Value(
Excel.XlRangeValueDataType.xlRangeValueDefault),
Object(,))
If ExcelCells IsNot Nothing Then
' Get bounds of the array.
Dim RowCount As Integer = ExcelCells.GetUpperBound(0)
For row As Integer = 1 To RowCount
If (ExcelCells(row, 1) IsNot Nothing) AndAlso (ExcelCells(row, 2) IsNot Nothing) Then
dtSheetData.Rows.Add(New Object() _
{
ExcelCells(row, 1),
ExcelCells(row, 2),
ExcelCells(row, 3)
}
)
End If
Next
End If
Finally
Release(xlUsedRange)
End Try
End If
xlWorkBook.Close()
xlApp.UserControl = True
xlApp.Quit()
Release(xlCells)
Release(xlWorkSheets)
Release(xlWorkSheet)
Release(xlWorkBook)
Release(xlWorkBooks)
Release(xlApp)
If Not Proceed Then
Throw New Exception("Failed to locate " & SheetName)
End If
Else
Throw New Exception("Failed to locate " & FileName)
End If
If HasHeader Then
If dtSheetData.Rows.Count > 0 Then
dtSheetData.Rows(0).Delete()
End If
End If
Return dtSheetData
End Function
Private Sub Release(ByVal sender As Object)
Try
If sender IsNot Nothing Then
Marshal.ReleaseComObject(sender)
sender = Nothing
End If
Catch ex As Exception
sender = Nothing
End Try
End Sub
End Module
另一种选择是通过OleDb数据提供者阅读,你可以看到MSDN code samples here中的例子,看一下项目Demo1_VB是一个简单的例子,而其他的则更复杂。