【问题标题】:How to export datagridview to excel using vb.net?如何使用 vb.net 将 datagridview 导出到 excel?
【发布时间】:2010-10-15 09:03:43
【问题描述】:

我在 vb.net 中有一个从数据库中填充的 datagridview。我进行了研究,发现没有内置支持直接从 datagridview 打印。我不想用水晶报表,因为我不熟悉。

我打算将它导出到 excel 中,以便我能够从 datagridview 生成报告。

你能给我提供方法吗?

【问题讨论】:

    标签: vb.net excel datagridview printing


    【解决方案1】:

    以下代码创建 Excel 文件并将其保存在 D: 驱动器中 它使用 Microsoft Office 2007

    首先将引用(Microsoft office 12.0 对象库)添加到您的项目

    然后将下面给出的代码添加到导出按钮单击事件-

    Private Sub Export_Button_Click(ByVal sender As System.Object, ByVal e As 
    System.EventArgs) Handles VIEW_Button.Click
    
        Dim xlApp As Microsoft.Office.Interop.Excel.Application
        Dim xlWorkBook As Microsoft.Office.Interop.Excel.Workbook
        Dim xlWorkSheet As Microsoft.Office.Interop.Excel.Worksheet
        Dim misValue As Object = System.Reflection.Missing.Value
        Dim i As Integer
        Dim j As Integer
    
        xlApp = New Microsoft.Office.Interop.Excel.ApplicationClass
        xlWorkBook = xlApp.Workbooks.Add(misValue)
        xlWorkSheet = xlWorkBook.Sheets("sheet1")
    
    
        For i = 0 To DataGridView1.RowCount - 2
            For j = 0 To DataGridView1.ColumnCount - 1
                For k As Integer = 1 To DataGridView1.Columns.Count
                    xlWorkSheet.Cells(1, k) = DataGridView1.Columns(k - 1).HeaderText
                    xlWorkSheet.Cells(i + 2, j + 1) = DataGridView1(j, i).Value.ToString()
                Next
            Next
        Next
    
        xlWorkSheet.SaveAs("D:\vbexcel.xlsx")
        xlWorkBook.Close()
        xlApp.Quit()
    
        releaseObject(xlApp)
        releaseObject(xlWorkBook)
        releaseObject(xlWorkSheet)
    
        MsgBox("You can find the file D:\vbexcel.xlsx")
    End Sub
    
    Private Sub releaseObject(ByVal obj As Object)
        Try
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub
    

    【讨论】:

    • 你把所有的东西都写成文本,为什么?摆脱 .ToString
    • 另外,循环是错误的方法。您需要创建一个对象数组并将其写入 Excel 中的一个范围。除了创建对象数组外,不需要循环。
    • @michaelZ。你有例子吗?
    • 我在下面的答案有一个创建对象数组然后将其设置为 Excel 中的范围的示例。如果您不需要格式化,那么您应该始终导出为 CSV,因为它比 Excel 自动化要快得多。我很乐意提供帮助。查看我的回答,如果您有任何问题,请告诉我。上面的答案很好,但您应该删除 .tostring 以便 Excel 中的数据类型正确。否则,您将拥有相当于 CSV 的内容,因为一切都是文本。
    【解决方案2】:

    Excel方法

    此方法与您将看到的许多方法不同。其他人使用循环来写入每个单元格并使用文本数据类型写入单元格。

    此方法从DataTableDataGridView 创建一个对象数组,然后将该数组写入 Excel。这意味着我可以在没有循环的情况下写入 Excel 并保留数据类型。

    我从我的库中提取了它,并且我认为我对其进行了足够的更改,以便仅使用此代码,但可能需要进行更多细微的调整。如果您遇到错误,请告诉我,我会为您更正。通常,我创建我的类的一个实例并调用这些方法。如果您想使用我的库,请使用此链接下载它,如果您需要帮助,请告诉我。
    https://zomp.co/Files.aspx?ID=zExcel


    将代码复制到您的解决方案后,您将像这样使用它。

    在您的按钮代码中添加此项并将名称更改为您的控件。

    WriteDataGrid("Sheet1", grid)

    要在导出后打开文件,请使用此行

    System.Diagnostics.Process.Start("The location and filename of your file")

    WriteArray 方法中,您需要将保存工作簿的行更改到您要保存的位置。将其添加为参数可能是有意义的。

    wb.SaveAs("C:\MyWorkbook.xlsx")


    Public Function WriteArray(Sheet As String, ByRef ObjectArray As Object(,)) As String
        Try
            Dim xl As Excel.Application = New Excel.Application
            Dim wb As Excel.Workbook = xl.Workbooks.Add()
            Dim ws As Excel.Worksheet = wb.Worksheets.Add()
            ws.Name = Sheet
            Dim range As Excel.Range = ws.Range("A1").Resize(ObjectArray.GetLength(0), ObjectArray.GetLength(1))
            range.Value = ObjectArray
    
            range = ws.Range("A1").Resize(1, ObjectArray.GetLength(1) - 1)
    
            range.Interior.Color = RGB(0, 70, 132)  'Con-way Blue
            range.Font.Color = RGB(Drawing.Color.White.R, Drawing.Color.White.G, Drawing.Color.White.B)
            range.Font.Bold = True
            range.WrapText = True
    
            range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter
            range.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter
    
            range.Application.ActiveWindow.SplitColumn = 0
            range.Application.ActiveWindow.SplitRow = 1
            range.Application.ActiveWindow.FreezePanes = True
    
            wb.SaveAs("C:\MyWorkbook.xlsx")
            wb.CLose()
            xl.Quit()
            xl = Nothing
            wb = Nothing
            ws  = Nothing
            range = Nothing
            ReleaseComObject(xl)
            ReleaseComObject(wb)
            ReleaseComObject(ws)
            ReleaseComObject(range)
    
            Return ""
        Catch ex As Exception
            Return "WriteArray()" & Environment.NewLine & Environment.NewLine & ex.Message
        End Try
    End Function
    
    Public Function WriteDataGrid(SheetName As String, ByRef dt As DataGridView) As String
            Try
                Dim l(dt.Rows.Count + 1, dt.Columns.Count) As Object
                For c As Integer = 0 To dt.Columns.Count - 1
                    l(0, c) = dt.Columns(c).HeaderText
                Next
    
                For r As Integer = 1 To dt.Rows.Count
                    For c As Integer = 0 To dt.Columns.Count - 1
                        l(r, c) = dt.Rows(r - 1).Cells(c)
                    Next
                Next
    
                Dim errors As String = WriteArray(SheetName, l)
                If errors <> "" Then
                    Return errors
                End If
    
                Return ""
            Catch ex As Exception
                Return "WriteDataGrid()" & Environment.NewLine & Environment.NewLine & ex.Message
            End Try
        End Function
    
    
     Public Function WriteDataTable(SheetName As String, ByRef dt As DataTable) As String
            Try
                Dim l(dt.Rows.Count + 1, dt.Columns.Count) As Object
                For c As Integer = 0 To dt.Columns.Count - 1
                    l(0, c) = dt.Columns(c).ColumnName
                Next
    
                For r As Integer = 1 To dt.Rows.Count
                    For c As Integer = 0 To dt.Columns.Count - 1
                        l(r, c) = dt.Rows(r - 1).Item(c)
                    Next
                Next
    
                Dim errors As String = WriteArray(SheetName, l)
                If errors <> "" Then
                    Return errors
                End If
    
                Return ""
            Catch ex As Exception
                Return "WriteDataTable()" & Environment.NewLine & Environment.NewLine & ex.Message
            End Try
        End Function
    

    我实际上并没有在我的数据库程序中使用这种方法,因为当您有很多行/列时,它是一种缓慢的方法。我改为从 DataGridView 创建一个 CSV。仅当您需要格式化数据和单元格时,使用 Excel 自动化写入 Excel 才有用,否则您应该使用 CSV。您可以使用图像后的代码进行 CSV 导出。


    CSV 方法

    Private Sub DataGridToCSV(ByRef dt As DataGridView, Qualifier As String)  
            Dim TempDirectory As String = "A temp Directory"  
            System.IO.Directory.CreateDirectory(TempDirectory)
            Dim oWrite As System.IO.StreamWriter
            Dim file As String = System.IO.Path.GetRandomFileName & ".csv"
            oWrite = IO.File.CreateText(TempDirectory & "\" & file)
    
            Dim CSV As StringBuilder = New StringBuilder()
    
            Dim i As Integer = 1
            Dim CSVHeader As StringBuilder = New StringBuilder()
            For Each c As DataGridViewColumn In dt.Columns
                If i = 1 Then
                    CSVHeader.Append(Qualifier & c.HeaderText.ToString() & Qualifier)
                Else
                    CSVHeader.Append("," & Qualifier & c.HeaderText.ToString() & Qualifier)
                End If
                i += 1
            Next
    
            'CSV.AppendLine(CSVHeader.ToString())
            oWrite.WriteLine(CSVHeader.ToString())
            oWrite.Flush()
    
            For r As Integer = 0 To dt.Rows.Count - 1
    
                Dim CSVLine As StringBuilder = New StringBuilder()
                Dim s As String = ""
                For c As Integer = 0 To dt.Columns.Count - 1
                    If c = 0 Then
                        'CSVLine.Append(Qualifier & gridResults.Rows(r).Cells(c).Value.ToString() & Qualifier)
                        s = s & Qualifier & gridResults.Rows(r).Cells(c).Value.ToString() & Qualifier
                    Else
                        'CSVLine.Append("," & Qualifier & gridResults.Rows(r).Cells(c).Value.ToString() & Qualifier)
                        s = s & "," & Qualifier & gridResults.Rows(r).Cells(c).Value.ToString() & Qualifier
                    End If
    
                Next
                oWrite.WriteLine(s)
                oWrite.Flush()
                'CSV.AppendLine(CSVLine.ToString())
                'CSVLine.Clear()
            Next
    
            'oWrite.Write(CSV.ToString())
    
            oWrite.Close()
            oWrite = Nothing    
    
            System.Diagnostics.Process.Start(TempDirectory & "\" & file)   
    
            GC.Collect()
    
        End Sub
    

    【讨论】:

    • 很棒的选择。我无法打开 zip 文件。 ReleaseComObject() 未在您发布的代码中定义。
    • 只需进入压缩文件的属性并将其设置为安全或其他东西。 Windows 这样做是因为它来自互联网。
    • ReleaseCOMObject 是 System.Runtime.InteropServices.Marshal 中的一个方法
    • 嗨,CSV 解决方案效果很好(经过一些调整)。但我无法让 Excel 解决方案正常工作。而且您的 zip 链接似乎已失效。
    • 我儿子不断重启我的机器,该机器在虚拟机中运行我的服务器。我会尽快恢复的。请随时直接与我联系以获取更多帮助。
    【解决方案3】:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        DATAGRIDVIEW_TO_EXCEL((DataGridView1)) ' PARAMETER: YOUR DATAGRIDVIEW
    End Sub
    
    Private Sub DATAGRIDVIEW_TO_EXCEL(ByVal DGV As DataGridView)
        Try
            Dim DTB = New DataTable, RWS As Integer, CLS As Integer
    
            For CLS = 0 To DGV.ColumnCount - 1 ' COLUMNS OF DTB
                DTB.Columns.Add(DGV.Columns(CLS).Name.ToString)
            Next
    
            Dim DRW As DataRow
    
            For RWS = 0 To DGV.Rows.Count - 1 ' FILL DTB WITH DATAGRIDVIEW
                DRW = DTB.NewRow
    
                For CLS = 0 To DGV.ColumnCount - 1
                    Try
                        DRW(DTB.Columns(CLS).ColumnName.ToString) = DGV.Rows(RWS).Cells(CLS).Value.ToString
                    Catch ex As Exception
    
                    End Try
                Next
    
                DTB.Rows.Add(DRW)
            Next
    
            DTB.AcceptChanges()
    
            Dim DST As New DataSet
            DST.Tables.Add(DTB)
            Dim FLE As String = "" ' PATH AND FILE NAME WHERE THE XML WIL BE CREATED (EXEMPLE: C:\REPS\XML.xml)
            DTB.WriteXml(FLE)
            Dim EXL As String = "" ' PATH OF/ EXCEL.EXE IN YOUR MICROSOFT OFFICE
            Shell(Chr(34) & EXL & Chr(34) & " " & Chr(34) & FLE & Chr(34), vbNormalFocus) ' OPEN XML WITH EXCEL
    
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    
    End Sub
    

    【讨论】:

      【解决方案4】:

      关于您需要“直接从 datagridview 打印”,请查看 CodeProject 上的这篇文章:

      The DataGridViewPrinter Class

      有许多类似的文章,但我很幸运地看到了我链接的那一篇。

      【讨论】:

        【解决方案5】:

        下面的代码对我来说很好:)

        Protected Sub ExportToExcel(sender As Object, e As EventArgs) Handles ExportExcel.Click
                Try
                    Response.Clear()
                    Response.Buffer = True
                    Response.AddHeader("content-disposition", "attachment;filename=ExportEthias.xls")
                    Response.Charset = ""
                    Response.ContentType = "application/vnd.ms-excel"
                    Using sw As New StringWriter()
                        Dim hw As New HtmlTextWriter(sw)
                        GvActifs.RenderControl(hw)
                        'Le format de base est le texte pour éviter les problèmes d'arrondis des nombres
                        Dim style As String = "<style> .textmode { } </style>"
                        Response.Write(Style)
                        Response.Output.Write(sw.ToString())
                        Response.Flush()
                        Response.End()
                    End Using
                Catch ex As Exception
                    lblMessage.Text = "Erreur export Excel : " & ex.Message
                End Try
            End Sub
            Public Overrides Sub VerifyRenderingInServerForm(control As Control)
                ' Verifies that the control is rendered
            End Sub
        

        希望对您有所帮助。

        【讨论】:

        • 感谢您的帮助!
        【解决方案6】:

        将 rowNo1 变暗 Dim numrow As Short Dim colNo1 As Short 将 colNo2 暗淡为短

            rowNo1 = 1
            colNo1 = 1
            colNo2 = 1
            numrow = 1
        
            ObjEXCEL = CType(CreateObject("Excel.Application"), Microsoft.Office.Interop.Excel.Application)
            objEXCELBook = CType(ObjEXCEL.Workbooks.Add, Microsoft.Office.Interop.Excel.Workbook)
            objEXCELSheet = CType(objEXCELBook.Worksheets(1), Microsoft.Office.Interop.Excel.Worksheet)
        
            ObjEXCEL.Visible = True
        
            For numCounter = 0 To grdName.Columns.Count - 1
                ' MsgBox(grdName.Columns(numCounter).HeaderText())
                If grdName.Columns(numCounter).Width > 0 Then
                    ObjEXCEL.Cells(1, numCounter + 1) = grdName.Columns(numCounter).HeaderText()
                End If
                ' ObjEXCEL.Cells(1, numCounter + 1) = grdName.Columns.GetFirstColumn(DataGridViewElementStates.Displayed)
            Next numCounter
        
            ObjEXCEL.Range("A:A").ColumnWidth = 10
            ObjEXCEL.Range("B:B").ColumnWidth = 25
            ObjEXCEL.Range("C:C").ColumnWidth = 20
            ObjEXCEL.Range("D:D").ColumnWidth = 20
            ObjEXCEL.Range("E:E").ColumnWidth = 20
            ObjEXCEL.Range("F:F").ColumnWidth = 25
        
            For rowNo1 = 0 To grdName.RowCount - 1
                For colNo1 = 0 To grdName.ColumnCount - 1
                    If grdName.Columns(colNo1).Width > 0 Then
                        If Trim(grdName.Item(colNo1, rowNo1).Value) <> "" Then
                            'If IsDate(grdName.Item(colNo1, rowNo1).Value) = True Then
                            '    ObjEXCEL.Cells(numrow + 1, colNo2) = Format(CDate(grdName.Item(colNo1, rowNo1).Value), "dd/MMM/yyyy")
                            'Else
                            ObjEXCEL.Cells(numrow + 1, colNo2) = grdName.Item(colNo1, rowNo1).Value
                            'End If
                        End If
                        If colNo2 >= grdName.ColumnCount Then
                            colNo2 = 1
                        Else
                            colNo2 = colNo2 + 1
                        End If
                    End If
                Next colNo1
                numrow = numrow + 1
            Next rowNo1
        

        【讨论】:

          【解决方案7】:

          在设计模式下:将DataGridView1 ClipboardCopyMode 属性设置为EnableAlwaysIncludeHeaderText

          还是关于程序代码

          DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
          

          在运行时选择所有单元格内容 (Ctrl+A) 并复制 (Ctrl+C) 并粘贴到 Excel 程序。 让 Excel 完成剩下的工作

          很抱歉,我一直在寻找直接从datagridvew打印数据的方法(从vb.net VB2012创建报告),没有找到满意的结果。 上面的代码只是我的,想知道我的应用程序用户是否可以依赖上面的简单步骤,这会很好,我可以继续下一步我的程序进度。

          【讨论】:

            【解决方案8】:

            从 Datagridview 生成可打印报表的一种简单方法是将 datagridview 放在 Panel 对象上。可以绘制面板的位图。

            这就是我的做法。

            '用面板的尺寸创建位图 Dim bmp As New Bitmap(Panel1.Width, Panel1.Height)

            '将Panel绘制到位图“bmp” Panel1.DrawToBitmap(bmp, Panel1.ClientRectangle)

            我通过“将我的 datagridview 项目分成页面来创建多页 tiff。 这就是我检测新页面开始的方式:

            '我一次将一行添加到我的数据网格中,然后检查滚动条是否处于活动状态。 '如果滚动条处于活动状态,我将行保存到变量中,然后将其从 'datagridview 并将我的计数器整数回滚一个(因此下一次运行将包括这个 '行。

            Private Function VScrollBarVisible() As Boolean
                Dim ctrl As New Control
                For Each ctrl In DataGridView_Results.Controls
                    If ctrl.GetType() Is GetType(VScrollBar) Then
                        If ctrl.Visible = True Then
                            Return True
                        Else
                            Return False
                        End If
                    End If
                Next
                Return Nothing
            End Function
            

            希望对你有帮助

            【讨论】:

              【解决方案9】:

              另一种更简单、更灵活的方法,在将数据加载到 Datagrid 之后

              Private Sub Button_Export_Click(sender As Object, e As EventArgs) Handles Button_Export.Click
                  Dim file As System.IO.StreamWriter
                  file = My.Computer.FileSystem.OpenTextFileWriter("c:\1\Myfile.csv", True)
                  If DataGridView1.Rows.Count = 0 Then GoTo loopend
              
                  ' collect the header's names 
                  Dim Headerline As String
                  For k = 0 To DataGridView1.Columns.Count - 1
                      If k = DataGridView1.Columns.Count - 1 Then ' last column dont put , separate 
                          Headerline = Headerline & DataGridView1.Columns(k).HeaderText
                      Else
                          Headerline = Headerline & DataGridView1.Columns(k).HeaderText & ","
                      End If
                  Next
                  file.WriteLine(Headerline)  ' this will write header names at the first line 
                  ' collect the data 
              
                  For i = 0 To DataGridView1.Rows.Count - 1
                      Dim DataRow As String
                      For k = 0 To DataGridView1.Columns.Count - 1
                          If k = DataGridView1.Columns.Count - 1 Then
                              DataRow = DataRow & DataGridView1.Rows(i).Cells(k).Value ' last column dont put , separate 
                          End If
                          DataRow = DataRow & DataGridView1.Rows(i).Cells(k).Value & ","
                      Next
              
                      file.WriteLine(DataRow)
                      DataRow = ""
                  Next
              
              
              
              loopend:
                      file.Close()
              End Sub
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-08-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-12-21
                相关资源
                最近更新 更多