0

Can anybody help me how to import data from datagridview to Microsoft Excel along with the column names and the data. And another thing is the date becomes hashtags. i have to expand the column to show the date.

i have a button and when i press it Microsoft excel should open with the data exported.

  • 1
    possible duplicate of http://stackoverflow.com/questions/680199/how-to-export-datagridview-to-excel-using-vb-net – Scott Craner May 23 '16 at 00:48
  • If you are exporting a lot of data then it would be more efficient to build a CSV file then open it with Excel. I can show you code for that if you want. I also have a library that wraps Excel automation. It contains a method that writes a DataTable to Excel. I assume your DataGridView has a datasource of DataTable. – Michael Z. May 23 '16 at 02:22

2 Answers2

-1

Excel Method

This method is different than many you will see. Others use a loop to write each cell and write the cells with text data type.

This method creates an object array from a DataTable or DataGridView and then writes the array to Excel. This means I can write to Excel without a loop and retain data types.

I extracted this from my library and I think I changed it enough to work with this code only, but more minor tweaking might be necessary. If you get errors just let me know and I'll correct them for you. Normally, I create an instance of my class and call these methods. If you would like to use my library then use this link to download it and if you need help just let me know.
https://zomp.co/Files.aspx?ID=zExcel


After copying the code to your solution you will use it like this.

In your button code add this and change the names to your controls.

WriteDataGrid("Sheet1", grid)

To open your file after exporting use this line

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

In the WriteArray method you'll want to change the line that saves the workbook to where you want to save it. Probably makes sense to add this as a parameter.

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

I actually don't use this method in my Database program because it's a slow method when you have a lot of rows/columns. I instead create a CSV from the DataGridView. Writing to Excel with Excel Automation is only useful if you need to format the data and cells otherwise you should use CSV. You can use the code after the image for CSV export.

DatabaseStudio


CSV Method

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
Michael Z.
  • 1,453
  • 1
  • 15
  • 21
  • then what will i put in my button? i am sorry but i am new to vb.net – catchyourwaves May 23 '16 at 11:25
  • `WriteDataTable("Sheet1", dt)` - You'll have to convert this to use DataGridView which isn't hard. – Michael Z. May 23 '16 at 12:01
  • This code won't function without the rest of it in my library. It is meant to help you write your own, but feel free to use my library. - https://zomp.co/Files.aspx?ID=zExcel – Michael Z. May 23 '16 at 12:26
  • I'll tweak this answer later today to be a copy and paste solution. – Michael Z. May 23 '16 at 12:27
  • I tweaked this and it should be copy and paste now. I even create a method for `DataGridView` You simply add the code to your project and call this from your button - `WriteDataGrid("Sheet1", grid)` – Michael Z. May 23 '16 at 13:15
  • I recommend using the CSV function. Keep in mind that I stripped these from my library so more minor tweaking might be necessary. If you comment with errors I will fix for you, but these methods will work for what you need. This is really just to help you implement your own, but I can help you get these working. – Michael Z. May 23 '16 at 15:26
  • l(r, c) = dt.Rows(r - 1).Cells(c).FormattedValue – NajiMakhoul Dec 23 '20 at 09:36
-1

Here is another solution that you can try, it uses GemBox.Spreadsheet library and it will keep the data type and the formatting that is used in the DataGridView:

Dim ef As New ExcelFile()
Dim ws = ef.Worksheets.Add("DGV Sheet")

' From DataGridView to ExcelFile.
DataGridViewConverter.ImportFromDataGridView(ws, dataGridView1,
    New ImportFromDataGridViewOptions() With {.ColumnHeaders = True})

' Auto fit excel columns.
Dim count As Integer = ws.CalculateMaxUsedColumns()
For index As Integer = 0 To count - 1
    ws.Columns(index).AutoFit()
Next

ef.Save("DGV Book.xlsx")

Also here you can find another sample.

Phouttrat
  • 24
  • 2
  • Free version only lets you export 150 rows. You could easily do what this library is doing. In fact, I have provided that code. – Michael Z. May 23 '16 at 13:29
  • Yes you're right, Free mode has size limitation. Nevertheless it was enough for my needs and hopefully it is to OP as well. Regarding your comment I'm not sure if you can easily do what this library is doing. First of all you can choose what format you want (CSV, XLS, XLSX, ODS, etc.), second it will keep the styling and the formatting that is used in DataGridView (like bold, italic, color, alignment, etc.), third it does not export just textual data but also hyperlinks, images, etc. – Phouttrat May 24 '16 at 07:19
  • It is easy actually. It's a pain wrapping all the functionality, but makes consuming Excel easier. I'm sure the product you're using bypasses Excel Automation if it doesn't then it's even worse than I thought. I don't claim mine to be better, but it is free and open source. In the OP's case, it probably makes more sense to export to CSV and open that in Excel. It's the fastest, easiest, and cheapest option. – Michael Z. May 24 '16 at 07:36
  • Pain and easy contradict each other... but anyway what I previously used for CSV export was OLEDB and it worked very well. After I needed more formats I switched to this solution and maintained the fast performances. The excel interop resulted in rather slow execution when I had bunch of images (regardless of their size) so it was not a choice for me... – Phouttrat May 24 '16 at 08:00
  • that makes sense to me...and I wasn't contadicting myself though. I meant pain as tedious not difficult – Michael Z. May 24 '16 at 08:03
  • How slow can your automation be with less than 150 rows to make you switch to this? I only get speed issues with 100,000 rows and 50 columns. That's when I switch to CSV. Then I can automate formatting if i need to, but that's never a thing because I either use predefined templates or I use analysis service like SSRS, SSAS, and PowerPivot. – Michael Z. May 24 '16 at 08:15
  • This is really not the discussion that we should be having :D, but nevertheless I see it like this: The more time the solution will take the more mistakes can be made (unless you're an Excel Interop expert :)), so I cannot say its easy (at least in a general sense, a lot of developers will not find this task to be easy at all). – Phouttrat May 24 '16 at 08:19
  • Well to answer your question in short, I had a multi-grid system and one of the bigger problem for me was image matrix. It could have up to 16384 images and this would yield rather poor execution time... – Phouttrat May 24 '16 at 08:34
  • I was just curious. It makes sense for that to be a slow process. I'm a little curious how you would use the image matrix now, but that's just really being off topic. – Michael Z. May 24 '16 at 08:40