将ListView导出到Excel - 苦苦挣扎的表现

时间:2017-05-29 14:31:04

标签: excel vb.net listview

我正在尝试优化我前一段时间编写的应用程序的输出,尽管我在很多方面取得了很多成就,但我仍在努力加快将listview的结果导出到.xlsx文件的功能。

我正在使用Interop来做,如下所示:

Imports Excel = Microsoft.Office.Interop.Excel
Imports System
Imports System.IO
Imports System.Data.OleDb
Imports System.Threading
Imports System.Linq
Imports System.Data.SqlClient

这是导出listview中数据的函数:

Private Function ExportListViewTab5ToXLSxFile(ByRef FileNameWithoutExtension As String, ByRef OutputDir As String) As Boolean

        Try
            Dim objExcel As Excel.Application = New Excel.Application
            Dim bkWorkBook As Excel.Workbook
            Dim shWorkSheet As Excel.Worksheet
            Dim i As Integer
            Dim j As Integer

            objExcel = New Excel.Application
            bkWorkBook = objExcel.Workbooks.Add
            shWorkSheet = CType(bkWorkBook.ActiveSheet, Excel.Worksheet)

            For i = 0 To lvObjectsTab5.Columns.Count - 1
                shWorkSheet.Cells(1, i + 1) = lvObjectsTab5.Columns(i).Text
            Next
            For i = 0 To lvObjectsTab5.Items.Count - 1
                For j = 0 To lvObjectsTab5.Items(i).SubItems.Count - 1
                    shWorkSheet.Cells(i + 2, j + 1) = lvObjectsTab5.Items(i).SubItems(j).Text
                Next
            Next

            shWorkSheet.Columns.AutoFit()

            Try

                '/////////////////
                '// Save report //
                '/////////////////
                Try
                    shWorkSheet.SaveAs(OutputDir & "\" & FileNameWithoutExtension & ".xlsx")
                Catch ex As Exception
                    MessageBox.Show("A exportação do relatório foi cancelada pelo usuário!", "Exportação cancelada!", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    Return False
                End Try

                '///////////////////////////////////
                '// Close EXCEL.EXE COM processes //
                '///////////////////////////////////

                bkWorkBook.Close()
                objExcel.Workbooks.Close()
                NAR(bkWorkBook)
                objExcel.Quit()
                NAR(objExcel)

                '//////////////////////////
                '// Open report in Excel //
                '//////////////////////////

                Process.Start(OutputDir & "\" & FileNameWithoutExtension & ".xlsx")
                Return True

            Catch ex As Exception
                MessageBox.Show("Falha ao exportar o arquivo '" & FileNameWithoutExtension & ".xlsx' para '" & OutputDir & "'", "Falha ao exportar relatório!" & vbCrLf & vbCrLf & _
                                "Detalhes do erro:" & vbCrLf & vbCrLf & _
                                ex.ToString, MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return False
            End Try
        Catch ex As Exception
            MessageBox.Show("Falha ao exportar o arquivo '" & FileNameWithoutExtension & ".xlsx' para '" & OutputDir & "'", "Falha ao exportar relatório!" & vbCrLf & vbCrLf & _
                            "Detalhes do erro:" & vbCrLf & vbCrLf & _
                            ex.ToString, MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return False
        End Try

    End Function

listview包含10列,导出2000行需要4分钟。太多了。我用谷歌搜索了几个小时,搜索了几个性能问题的例子,但我发现的所有例子都与我的相似。

有人可以指导我如何使用.NET代码提高函数的性能吗?在典型情况下,此列表视图列出了15000行。我限制在2000,所以对用户来说不那么痛苦。

有什么建议吗?

提前致谢, 丹尼尔

1 个答案:

答案 0 :(得分:1)

尝试一次性将所有值应用为范围。像这样的东西可能会这样做。

dim Values(lvObjectsTab5.Items.Count, lvObjectsTab5.Items(i).SubItems.Count) as object
dim Range as Excel.Range = shWorkSheet.Range("A1","J" & (lvObjectsTab5.Items.Count+ 1))

For i = 0 To lvObjectsTab5.Columns.Count - 1
    Values(0, i ) = lvObjectsTab5.Columns(i).Text
Next

For i = 0 To lvObjectsTab5.Items.Count - 1
        For j = 0 To lvObjectsTab5.Items(i).SubItems.Count - 1
            Values(i+1,j) = lvObjectsTab5.Items(i).SubItems(j).Text
        Next
Next
Range.value = Values

编辑:在值矩阵中插入列标题。