lunes, 7 de marzo de 2011

Exportar a Excel desde un DataGridView VB.NET

Hola a todos,
Es esta mi primera publicación, por tanto pedire que se me haga criticas constructivas.
Lo que haremos será:
-- Exportar a excel desde un datagridview
-- Exportar a varias hojas de excel desde un conjunto de datagridview

EXPORTAR A EXCEL DESDE UN DATAGRIDVIEW.

Lo primero que debemos hacer es crear nuestro formulario, insertar el datagridview y le daremos el siguiente formato, para que sea vea un poco mas presentable:

AllowUserToAddRows = False
AllowUserToDeleteRows = False
Archor = Top, Bottom, Left, Right
BackGround = Window
MultiSelect = False
ReadOnly = true
SelectionMode = FullRowSelect

una ves creado nuestro DataGridView lo cargamos y nos deberia quedar con el formulario masomenos asi:



Si queremos que al inciar el datagrid no se seleccione la fila por defecto hacemos lo siguiente en el evento load o el boton que llame al cargar el datagrid:

Me.dgv1.CurrentCell = Nothingme.dgv1.clearselection()

Ahora  procederemos a exportar:

Lo primero que tenemos que hacer es agregar referencia:


Agregada la referencia Procedemos a exportar: en el evento que lo dispara en mi caso un boton exportar:

Private Sub btnExportar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExportar.Click

Dim app As Microsoft.Office.Interop.Excel._Application = New Microsoft.Office.Interop.Excel.Application()
Dim workbook As Microsoft.Office.Interop.Excel._Workbook = app.Workbooks.Add(Type.Missing)
Dim worksheet As Microsoft.Office.Interop.Excel._Worksheet = Nothingworksheet = workbook.Sheets("Hoja1")
worksheet = workbook.ActiveSheet
'Aca se agregan las cabeceras de nuestro datagrid.

For i As Integer = 1 To Me.dgvCasosPendientes.Columns.Count
      worksheet.Cells(1, i) = Me.dgvCasosPendientes.Columns(i - 1).HeaderText
Next

'Aca se ingresa el detalle recorrera la tabla celda por celda

For i As Integer = 0 To Me.dgvCasosPendientes.Rows.Count - 1
For j As Integer = 0 To Me.dgvCasosPendientes.Columns.Count - 1
worksheet.Cells(i + 2, j + 1) = Me.dgvCasosPendientes.Rows(i).Cells(j).Value.ToString()
NextNext

'Aca le damos el formato a nuestro excel

worksheet.Rows.Item(1).Font.Bold = 1
worksheet.Rows.Item(1).HorizontalAlignment = 3
worksheet.Columns.AutoFit()
worksheet.Columns.HorizontalAlignment = 2

app.Visible = Trueapp = Nothingworkbook = Nothing
worksheet = NothingFileClose(1)
GC.Collect()
End Sub 
Ahora ejecutamos el programa y el resultado:




Ahora pasamos a la fase 2:
EXPORTAR A VARIAS HOJAS DE EXCEL DESDE VARIOS DATA GRID: VB.Net

Si queremos exportar a un archivo de excel con varias hojas debemos de considerar lo siguiente:
Un DataGridView Será una hoja de excel.

No les dire como llenaran todos los datagridview que necesiten o cual es la mejor forma, lo que yo hize es crear un objeto data set y asignar cada tabla del dataset a un datagridview asi:

Me.DataGridView0.DataSource = ds.Tables(0)
Me.DataGridView1.DataSource = ds.Tables(1)
Me.DataGridView2.DataSource = ds.Tables(2)
Me.DataGridView3.DataSource = ds.Tables(3)
Me.DataGridView4.DataSource = ds.Tables(4)
Me.DataGridView5.DataSource = ds.Tables(5)
Me.DataGridView6.DataSource = ds.Tables(6)
Me.DataGridView7.DataSource = ds.Tables(7)
Me.DataGridView8.DataSource = ds.Tables(8)

Ahora codificacremos para exportar es algo similar al anterior ahi les va el codigo:

Private Sub btnExportar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExportar.Click

' Creacion de la aplicacion en excelDim app As Microsoft.Office.Interop.Excel._Application = New Microsoft.Office.Interop.Excel.Application()
' Creamos nueva hoja de trabajao en la aplicacin excelDim workbook As Microsoft.Office.Interop.Excel._Workbook = app.Workbooks.Add(Type.Missing)
' Creando nueva hoja de trabajo en el libroDim worksheet As Microsoft.Office.Interop.Excel._Worksheet = Nothing'Obtenemos la referencia de la primera hoja que por el momento tiene nombre Hoja1
 worksheet = workbook.Sheets("Hoja3")
worksheet = workbook.Sheets("Hoja2")
worksheet = workbook.Sheets("Hoja1")
worksheet = workbook.ActiveSheet
'creamos nuevas hojasworkbook.Sheets.Add(After:=workbook.Worksheets("Hoja3"))
workbook.Sheets.Add(After:=workbook.Worksheets("Hoja4"))
workbook.Sheets.Add(After:=workbook.Worksheets("Hoja5"))
workbook.Sheets.Add(After:=workbook.Worksheets("Hoja6"))
workbook.Sheets.Add(After:=workbook.Worksheets("Hoja7"))
workbook.Sheets.Add(After:=workbook.Worksheets("Hoja8"))

' Enviamos al excel por hojas'hoja 1For c As Integer = 1 To Me.dgvAmpliatorioDinamico.Columns.Count
workbook.Sheets("Hoja1").Cells(1, c) = Me.dgvAmpliatorioDinamico.Columns(c - 1).HeaderText
NextFor c As Integer = 0 To Me.dgvAmpliatorioDinamico.Rows.Count - 1
For d As Integer = 0 To Me.dgvAmpliatorioDinamico.Columns.Count - 1
workbook.Sheets("Hoja1").Cells(c + 2, d + 1) = Me.dgvAmpliatorioDinamico.Rows(c).Cells(d).Value.ToString()
NextNext'hoja2 For a As Integer = 1 To Me.DataGridView1.Columns.Count
workbook.Sheets("Hoja2").Cells(1, a) = Me.DataGridView1.Columns(a - 1).HeaderText
NextFor a As Integer = 0 To Me.DataGridView1.Rows.Count - 1
For b As Integer = 0 To Me.DataGridView1.Columns.Count - 1
workbook.Sheets("Hoja2").Cells(a + 2, b + 1) = Me.DataGridView1.Rows(a).Cells(b).Value.ToString()
NextNext'hoja3For f As Integer = 1 To Me.DataGridView2.Columns.Count
workbook.Sheets("Hoja3").Cells(1, f) = Me.DataGridView2.Columns(f - 1).HeaderText
NextFor f As Integer = 0 To Me.DataGridView2.Rows.Count - 1
For g As Integer = 0 To Me.DataGridView2.Columns.Count - 1
workbook.Sheets("Hoja3").Cells(f + 2, g + 1) = Me.DataGridView2.Rows(f).Cells(g).Value.ToString()
NextNext
.
.
.'hoja7'hoja8'hoja9
'Damos formato a todas las hojas a traves de una sentencia repetitiva.For l As Integer = 1 To 9
Dim Hoja As String = "Hoja" & l
workbook.Sheets(Hoja).Rows.Item(1).Font.Bold = 1
workbook.Sheets(Hoja).Rows.Item(1).HorizontalAlignment = 3
workbook.Sheets(Hoja).Columns.AutoFit()
workbook.Sheets(Hoja).Columns.HorizontalAlignment = 2
Next
 'Cambiamos el nombre de las hojas  para que se entiendaworkbook.Worksheets("Hoja1").Name = "Cambio de Centro Médico"workbook.Worksheets("Hoja2").Name = "Cambio de Médico Auditor"workbook.Worksheets("Hoja3").Name = "Hospitalizacion"workbook.Worksheets("Hoja4").Name = "Visita Hospitalaria"workbook.Worksheets("Hoja5").Name = "Invalidez"workbook.Worksheets("Hoja6").Name = "Muerte"workbook.Worksheets("Hoja7").Name = "Alta"workbook.Worksheets("Hoja8").Name = "Traslado a Provincia"workbook.Worksheets("Hoja9").Name = "Movilidad"' Para abrir el excelapp.Visible = True'Salir de la aplicacin borrar de memoria, los archivos basura y todo app = Nothingworkbook = Nothingworksheet = NothingFileClose(1)
GC.Collect()
End Sub

y aqui obtenemos el resultado:

Como pueden apreciar se ha creado 9 hojas de excel dentro del archivo y como ven seleccione una hoja al azar y ven todos los datos exportados.

Espero ayudarlos un poco en sus tareas cotidianas. de hecho se pueden hacer muchas modificaciones  para hacerlo mas optimo, y si hacen que funcione mejor pueden compartir aqui en este blog. Gracias.

43 comentarios:

  1. Hola Luis Felipe. Antes que nada, excelente aporte. Una pregunta, qué pasa si quisiera exportar un dgv a un archivo de excel con un formato prestablecido? Es decir, a un archivo de excel que en sus hojas ya tenga formatos como títulos y gráficas? Gracias de antemano. Saludos!

    ResponderEliminar
  2. Buen día Cristian, el archivo de excel se abre en memoria, al cerrar el archivo te preguntara si deseas guardar el archivo.

    ResponderEliminar
  3. Hola que tal, una consulta tengo un codigo para exportar datos del datagridview al excel con un progressbar, pero cuando esta exportando no se como cancelar lo que esta exportando.

    Saludos,

    ResponderEliminar
  4. Hola, Julian quieres detener el proceso? en un determinado momento si es así podrías probar con el exit sub o exit function dependiendo de cual sea el proceso.

    ResponderEliminar
  5. gracias brother me hiciste el dia we gracias

    ResponderEliminar
  6. Amigo necesito ayuda con tu codigo o alguien que me ayude, me marca el error de ambigüedad

    ResponderEliminar
  7. en la linea cuando estas declarando
    Dim app As Microsoft.Office.Interop.Excel._Application = New Microsoft.Office.Interop.Excel.Application()
    Dim workbook As Microsoft.Office.Interop.Excel._Workbook = app.Workbooks.Add(Type.Missing)
    Dim worksheet As Microsoft.Office.Interop.Excel._Worksheet = Nothingworksheet = workbook.Sheets("Hoja1")
    worksheet = workbook.ActiveSheet

    dice que worksheet es ambigüo, quisiera si fueras tan amable y me pudieras enviar un ejemplo a mi20rg@hotmail.com

    es que estoy creando un programita y tus funciones son las que necesito.

    Gracias por tu apoyo

    ResponderEliminar
  8. Me podrias mandar los 2 ejemplos a mi correo, gracias.
    el de que exporta varios datagridview saludos

    venenolabs@gmail.com


    ResponderEliminar
  9. Felipe, me puedes facilitar el código de la búsqueda con los dos datetimepicker ?
    Jclarkwu68@gmail.com

    ResponderEliminar
  10. Que pasa si no tengo la referencia microsoft.office.interop? soy bastante nuevo en esto del vb. Hay alguna manera de instalarla.
    Gracias

    ResponderEliminar
  11. Si no tienes la referencia interop no podrás realizar dicho ejemplo.

    ResponderEliminar
  12. como puedo agregar la referencia microsoft.office.interop? . PD no aparce en mi listado .NET

    ResponderEliminar
  13. tienes que tener instalado el office.

    ResponderEliminar
  14. Luis Felipe que tal, si el libro de excel contiene imágenes, como las puedo visualizar en el datagridview

    ResponderEliminar
  15. Buenas una pregunta si deseo agregar una cabecera predeterminada a mi excel como seria el codigo para realizar dicho reporte

    ResponderEliminar
  16. Hola. Copa América, por cual motivo deseas agregar una cabecera predeterminada, lo que yo podría hacer es agregar al datatable o al gridview una columna justo antes de empezar el procedimiento de exportación.

    ResponderEliminar
  17. Hola.
    Alan, lo que puedes hacer es tener en tu gridview una columna oculta donde tengas la ruta completa de donde se encuentra la imagen. Saludos.

    ResponderEliminar
  18. amigo buenas tardes yo tengo este codigo pero cuando exporta a excel solo me muestra el ultimo ingreso que se genero en el datagrid te lo dejo a ver si me corriges y vez que estoy haciendo mal

    Public Sub ExportarDatosExcel(ByVal DataGridView1 As DataGridView, ByVal titulo As String)
    Dim m_Excel As New Excel.Application
    m_Excel.Cursor = Excel.XlMousePointer.xlDefault
    m_Excel.Visible = True
    Dim objLibroExcel As Excel.Workbook = m_Excel.Workbooks.Add
    Dim objHojaExcel As Excel.Worksheet = objLibroExcel.Worksheets(1)
    With objHojaExcel
    .Visible = Excel.XlSheetVisibility.xlSheetVisible
    .Activate()
    'Encabezado
    .Range("A1:L1").Merge()
    .Range("A1:L1").Value = "Informe de Registros"
    .Range("A1:L1").Font.Bold = True
    .Range("A1:L1").Font.Size = 15
    'Copete
    .Range("A2:L2").Merge()
    .Range("A2:L2").Value = titulo
    .Range("A2:L2").Font.Bold = True
    .Range("A2:L2").Font.Size = 12

    Const primeraLetra As Char = "A"
    Const primerNumero As Short = 3
    Dim Letra As Char, UltimaLetra As Char
    Dim Numero As Integer, UltimoNumero As Integer
    Dim cod_letra As Byte = Asc(primeraLetra) - 1
    Dim sepDec As String = Application.CurrentCulture.NumberFormat.NumberDecimalSeparator
    Dim sepMil As String = Application.CurrentCulture.NumberFormat.NumberGroupSeparator
    'Establecer formatos de las columnas de la hija de cálculo
    Dim strColumna As String = ""
    Dim LetraIzq As String = ""
    Dim cod_LetraIzq As Byte = Asc(primeraLetra) - 1
    Letra = primeraLetra
    Numero = primerNumero
    Dim objCelda As Excel.Range
    For Each c As DataGridViewColumn In DGVconsulta.Columns
    If c.Visible Then
    If Letra = "Z" Then
    Letra = primeraLetra
    cod_letra = Asc(primeraLetra)
    cod_LetraIzq += 1
    LetraIzq = Chr(cod_LetraIzq)
    Else
    cod_letra += 1
    Letra = Chr(cod_letra)
    End If
    strColumna = LetraIzq + Letra + Numero.ToString
    objCelda = .Range(strColumna, Type.Missing)
    objCelda.Value = c.HeaderText
    objCelda.EntireColumn.Font.Size = 8
    'objCelda.EntireColumn.NumberFormat = c.DefaultCellStyle.Format
    If c.ValueType Is GetType(Decimal) OrElse c.ValueType Is GetType(Double) Then
    objCelda.EntireColumn.NumberFormat = "#" + sepMil + "0" + sepDec + "00"
    End If
    End If
    Next

    ResponderEliminar
  19. Dim objRangoEncab As Excel.Range = .Range(primeraLetra + Numero.ToString, LetraIzq + Letra + Numero.ToString)
    objRangoEncab.BorderAround(1, Excel.XlBorderWeight.xlMedium)
    UltimaLetra = Letra
    Dim UltimaLetraIzq As String = LetraIzq

    'CARGA DE DATOS
    Dim i As Integer = Numero + 1

    For Each reg As DataGridViewRow In DGVconsulta.Rows
    LetraIzq = ""
    cod_LetraIzq = Asc(primeraLetra) - 1
    Letra = primeraLetra
    cod_letra = Asc(primeraLetra) - 1
    For Each c As DataGridViewColumn In DGVconsulta.Columns
    If c.Visible Then
    If Letra = "Z" Then
    Letra = primeraLetra
    cod_letra = Asc(primeraLetra)
    cod_LetraIzq += 1
    LetraIzq = Chr(cod_LetraIzq)
    Else
    cod_letra += 1
    Letra = Chr(cod_letra)
    End If
    strColumna = LetraIzq + Letra
    ' acá debería realizarse la carga
    .Cells(i, strColumna) = IIf(IsDBNull(reg.ToString), "", reg.Cells(c.Index).Value)
    '.Cells(i, strColumna) = IIf(IsDBNull(reg.(c.DataPropertyName)), c.DefaultCellStyle.NullValue, reg(c.DataPropertyName))
    '.Range(strColumna + i, strColumna + i).In()

    End If
    Next
    Dim objRangoReg As Excel.Range = .Range(primeraLetra + i.ToString, strColumna + i.ToString)
    objRangoReg.Rows.BorderAround()
    objRangoReg.Select()
    i += 1
    Next
    UltimoNumero = i

    'Dibujar las líneas de las columnas
    LetraIzq = ""
    cod_LetraIzq = Asc("A")
    cod_letra = Asc(primeraLetra)
    Letra = primeraLetra
    For Each c As DataGridViewColumn In DGVconsulta.Columns
    If c.Visible Then
    objCelda = .Range(LetraIzq + Letra + primerNumero.ToString, LetraIzq + Letra + (UltimoNumero - 1).ToString)
    objCelda.BorderAround()
    If Letra = "Z" Then
    Letra = primeraLetra
    cod_letra = Asc(primeraLetra)
    LetraIzq = Chr(cod_LetraIzq)
    cod_LetraIzq += 1
    Else
    cod_letra += 1
    Letra = Chr(cod_letra)
    End If
    End If
    Next

    'Dibujar el border exterior grueso
    Dim objRango As Excel.Range = .Range(primeraLetra + primerNumero.ToString, UltimaLetraIzq + UltimaLetra + (UltimoNumero - 1).ToString)
    objRango.Select()
    objRango.Columns.AutoFit()
    objRango.Columns.BorderAround(1, Excel.XlBorderWeight.xlMedium)
    End With

    'm_Excel.Cursor = Excel.XlMousePointer.xlDefault

    'esta siguiente linea comentada
    m_Excel.Cursor = Excel.XlMousePointer.xlDefault

    'Aca almacenar en la ruta especificada de un directorio
    m_Excel.ActiveWorkbook.SaveAs(Filename:=Application.StartupPath & "\registro1.xls")
    m_Excel.ActiveWorkbook.Close(False)

    'Cierra el archivo y elimina la variable m_Excel.Quit()
    m_Excel = Nothing

    End Sub

    ResponderEliminar
  20. Me podrias mandar los 2 ejemplos a mi correo, gracias.
    el de que exporta varios datagridview saludos..

    ruls_mg00@hotmail.com

    ResponderEliminar
  21. muchas gracia brother, fue de mucha utilidad tu aporte, mil y un gracias!

    ResponderEliminar
  22. Que pasaría si tengo una gran cantidad de registros en el datagridview, por ejemplo 20,000.
    El proceso de exportación parecería que quedaría colgado.
    Saludos,

    ResponderEliminar
  23. Como tendria que hacer para exportar los datos a un excel ya existente?

    ResponderEliminar
  24. Hola Alberth Estoy trabajando sobre una nueva entrada referente a lo que pides. en unos días publicaré el ejemplo.

    ResponderEliminar
  25. Para quien preguntò por el path del archivo, este no es necesario ya que el codigo crea el archivo excel. En esta aplicaciòn ya te preguntará si deseas guardar el archivo. Buena publicación. Yo hace años hice desde vb6 y tengo la necesidad de hacerlo desde vb net. Pude incluir codigo vba de excel en mi programa vb6 de tal modo dibujar lineas, dar formatos, etc. Asi que con esta base me aplico y compartire mi experiencia ya que hay alguna pregunta al respecto. Hasta pronto, no pasa de mañana pues el lunes tengo que entregar el trabajo solicitado. Gracias

    ResponderEliminar
  26. me puedes mandar el ejemplo porfa jreynosa1@gmail.com

    ResponderEliminar
  27. hola! por favor me puedes enviar el ejemplo wvilladiego@gmail.com

    ResponderEliminar
  28. Hola, esto sigue vigente? Tienes alguna actualización?
    Quisiera usarlo con la paginación del grid....

    ResponderEliminar
  29. Muchas Gracias, mil bendiciones para ti y toda la buena energía

    ResponderEliminar
  30. Amigo me podria ayudar con el codigo fuente. Como subirlo a la nube please

    ResponderEliminar
  31. Luis una consulta y si quisiera guardarlo en mis documentos?

    ResponderEliminar
  32. Luis una consulta y si quisiera guardarlo en mis documentos?

    ResponderEliminar
  33. Luis Felipe, buen día. Te agradezco mucho el material que pusiste en tu blog, realemente recomendado.
    Gracias por el aporte, muy gentil...
    Verdaderamente práctico.

    ResponderEliminar
  34. Necesito el archivo no se si me podrías dar para mi proyecto
    por favor le agradecería bastante.

    ResponderEliminar
  35. Saludos alguien que me pueda ayudar Exportando y Importando
    Esto es lo que echo Ayuda
    ________________________________
    Sub GridAExcel(ByVal Dgv As DataGridView)
    Dim documento As Microsoft.Office.Interop.Excel._Application = New Microsoft.Office.Interop.Excel.Application
    Dim libro As Microsoft.Office.Interop.Excel._Workbook = documento.Workbooks.Add(Type.Missing)
    Dim hoja As Microsoft.Office.Interop.Excel._Worksheet = Nothing

    Dim nombre_col, valor As String
    'caracteristicas de las hojas
    hoja = libro.Worksheets("Hoja1")
    hoja = libro.ActiveSheet

    'extrae los nombre de la colum del dtaview
    For i As Integer = 1 To Dgv.ColumnCount
    nombre_col = Dgv.Columns(i - 1).HeaderText
    hoja.Cells(1, i) = nombre_col
    Next

    'dando formato Hoja
    hoja.Rows.Item(1).Font.Bold = 1
    hoja.Rows.Item(1).HorizontalAlignment = 3
    hoja.Columns.AutoFit()
    hoja.Columns.HorizontalAlignment = 2


    ''extraer los registro
    For i As Integer = 0 To Dgv.RowCount - 2
    For j As Integer = 0 To Dgv.ColumnCount - 1
    valor = dgv_Jugador.Rows(i).Cells(j).Value
    hoja.Cells(i + 2, j + 1) = valor
    Next
    Next

    documento.Visible = True
    End Sub
    ________________________________

    ResponderEliminar
  36. luis felipe me puedes enviar los ejemplos a mi correo electronico? enric.andilla.lopez@hotmail.com

    ResponderEliminar
  37. Luis Felipe Una consulta en mi datagridview tengo ya definidos ciertas celdas con colores cuando lo exporto se gurda correctamente pero me gustaria que a la hora de exportar tambien exporte con los colores que ya estan en el datagrid view nose si porfavor me puedes ayudar.
    solo me falta exportar con los colores que ya esta en mi data gridview
    de antemano gracias y espero me puedas dar una pequeña ayuda.


    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim SAVE As New SaveFileDialog
    Dim ruta As String
    Dim xlApp As Object = CreateObject("Excel.Application")
    Dim pth As String = ""
    'crearemos una nueva hoja de calculo
    Dim xlwb As Object = xlApp.WorkBooks.add
    Dim xlws As Object = xlwb.WorkSheets(1)
    Try
    'exportaremos los caracteres de las columnas
    For c As Integer = 0 To DataGridView1.Columns.Count - 1
    xlws.cells(1, c + 1).value = DataGridView1.Columns(c).HeaderText
    Next
    'exportaremos las cabeceras de las calumnas
    For r As Integer = 0 To DataGridView1.RowCount - 1
    For c As Integer = 0 To DataGridView1.Columns.Count - 1
    xlws.cells(r + 2, c + 1).value = Convert.ToString(DataGridView1.Item(c, r).Value)

    Next
    Next

    'guardamos la hoja de excel en la ruta especifica
    Dim SaveFileDialog1 As SaveFileDialog = New SaveFileDialog
    SaveFileDialog1.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
    SaveFileDialog1.Filter = "Archivo Excel| *.xlsx"
    SaveFileDialog1.FilterIndex = 2
    If SaveFileDialog1.ShowDialog = DialogResult.OK Then
    ruta = SaveFileDialog1.FileName
    xlwb.saveas(ruta)
    xlws = Nothing
    xlwb = Nothing
    xlApp.quit()
    MsgBox("Exportado Correctamente", MsgBoxStyle.Information)
    End If

    Catch ex As Exception
    End Try
    End Sub

    ResponderEliminar
  38. Muchas gracias, funcionó a la primera.

    ResponderEliminar