如何使用vb.net将datagridview导出到excel?

时间:2009-03-25 04:17:06

标签: vb.net excel datagridview printing

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

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

你能告诉我这样做的方法吗?

9 个答案:

答案 0 :(得分:16)

下面的代码创建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

答案 1 :(得分:6)

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 Automation写入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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

The DataGridViewPrinter Class

有很多类似的文章,但我很幸运能与之相关的文章。

答案 4 :(得分:1)

以下代码适用于我:)

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

希望这对你有所帮助。

答案 5 :(得分:0)

Dim rowNo1 As Short         Dim numrow As Short         Dim colNo1 As Short         Dim colNo2 As Short

    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

答案 6 :(得分:0)

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

或程序代码

DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText

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

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

答案 7 :(得分:0)

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

我是这样做的。

'使用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

我希望这会有所帮助

答案 8 :(得分:0)

将数据加载到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