visual studio metodos formato form exportar datos con agregar c# datagridview copy export-to-excel export-to-csv

c# - studio - ¿Cómo exportar datos de dataGridView instantáneamente a Excel con un clic en el botón?



exportar datos de un datagridview a excel en vb 2010 (9)

Tengo 10k filas y 15 columnas en mi vista de cuadrícula de datos. Quiero exportar estos datos a una hoja de Excel o haga clic en el botón. Ya lo he intentado con el siguiente código.

private void btExport_Click(object sender, EventArgs e) { Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application(); Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing); Microsoft.Office.Interop.Excel._Worksheet worksheet = null; app.Visible = true; worksheet = workbook.Sheets["Sheet1"]; worksheet = workbook.ActiveSheet; for(int i=1;i<dataGridView1.Columns.Count+1;i++) { worksheet.Cells[1, i] = dataGridView1.Columns[i-1].HeaderText; } for (int i=0; i < dataGridView1.Rows.Count-1 ; i++) { for(int j=0;j<dataGridView1.Columns.Count;j++) { if (dataGridView1.Rows[i].Cells[j].Value != null) { worksheet.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString(); } else { worksheet.Cells[i + 2, j + 1] = ""; } } } }

Esto está funcionando para mí, pero lleva mucho tiempo completar el proceso de exportación.

¿Es posible exportar desde dataGridView (con 10k filas) para sobresalir al instante con un botón?

Aparte de esto, cuando intenté copiar todo el contenido de dataGridview al portapapeles y luego pegarlo en la hoja de Excel manualmente, sucedió casi al instante.

Entonces, ¿hay una manera de copiar todas las celdas dataGridView al portapapeles y pegarlas en la hoja de Excel (con formato de celda) en un botón?

Tengo el código para copiar al portapapeles como se muestra a continuación, pero no sé cómo pegarlo en una nueva hoja de Excel abriéndola.

private void copyAllToolStripMenuItem_Click(object sender, EventArgs e) { dataGridView1.SelectAll(); DataObject dataObj = dataGridView1.GetClipboardContent(); if (dataObj != null) Clipboard.SetDataObject(dataObj); }

Por favor ayuda con un ejemplo. Soy nuevo en C #.


Esta es una gran pregunta y me sorprendió lo difícil que era encontrar una respuesta clara y completa, la mayoría de las respuestas que encontré eran sudo-code o no estaban completas al 100%.

Pude crear una solución completa para copiar y guardar los datos de mi DataGridView en un archivo de Excel basado en la respuesta de Jake, así que estoy publicando mi solución completa con la esperanza de que pueda ayudar a otros recién llegados a c # como yo :)

En primer lugar, necesitará la referencia Microsoft.Office.Interop.Excel en su proyecto. Ver MSDN sobre cómo agregarlo.

Mi código:

using Excel = Microsoft.Office.Interop.Excel; private void btnExportToExcel_Click(object sender, EventArgs e) { SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "Excel Documents (*.xls)|*.xls"; sfd.FileName = "Inventory_Adjustment_Export.xls"; if (sfd.ShowDialog() == DialogResult.OK) { // Copy DataGridView results to clipboard copyAlltoClipboard(); object misValue = System.Reflection.Missing.Value; Excel.Application xlexcel = new Excel.Application(); xlexcel.DisplayAlerts = false; // Without this you will get two confirm overwrite prompts Excel.Workbook xlWorkBook = xlexcel.Workbooks.Add(misValue); Excel.Worksheet xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); // Format column D as text before pasting results, this was required for my data Excel.Range rng = xlWorkSheet.get_Range("D:D").Cells; rng.NumberFormat = "@"; // Paste clipboard results to worksheet range Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1]; CR.Select(); xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true); // For some reason column A is always blank in the worksheet. ¯/_(ツ)_/¯ // Delete blank column A and select cell A1 Excel.Range delRng = xlWorkSheet.get_Range("A:A").Cells; delRng.Delete(Type.Missing); xlWorkSheet.get_Range("A1").Select(); // Save the excel file under the captured location from the SaveFileDialog xlWorkBook.SaveAs(sfd.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue); xlexcel.DisplayAlerts = true; xlWorkBook.Close(true, misValue, misValue); xlexcel.Quit(); releaseObject(xlWorkSheet); releaseObject(xlWorkBook); releaseObject(xlexcel); // Clear Clipboard and DataGridView selection Clipboard.Clear(); dgvItems.ClearSelection(); // Open the newly saved excel file if (File.Exists(sfd.FileName)) System.Diagnostics.Process.Start(sfd.FileName); } } private void copyAlltoClipboard() { dgvItems.SelectAll(); DataObject dataObj = dgvItems.GetClipboardContent(); if (dataObj != null) Clipboard.SetDataObject(dataObj); } private void releaseObject(object obj) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null; } catch (Exception ex) { obj = null; MessageBox.Show("Exception Occurred while releasing object " + ex.ToString()); } finally { GC.Collect(); } }


Esta respuesta es para la primera pregunta, por qué lleva tanto tiempo y ofrece una solución alternativa para exportar el DataGridView a Excel.

MS Office Interop es lento e incluso Microsoft no recomienda el uso de Interoperabilidad en el lado del servidor y no puede utilizarse para exportar archivos de Excel grandes. Para más detalles, vea por qué no usar la automatización OLE desde el punto de vista de Microsoft.

Interop guarda los archivos de Excel en formato de archivo XLS (antiguo formato de archivo de Excel 97-2003) y el soporte para Office 2003 ha finalizado. Microsoft Excel lanzó el formato de archivo XLSX con Office 2007 y recomienda el uso de OpenXML SDK en lugar de Interop. Pero los archivos XLSX no son realmente tan rápidos y no manejan archivos de Excel muy grandes porque se basan en el formato de archivo XML. Esta es la razón por la que Microsoft también lanzó el formato de archivo XLSB con Office 2007, formato de archivo que se recomienda para archivos grandes de Excel. Es un formato binario. Así que la mejor y más rápida solución es guardar archivos XLSB.

Puede usar esta biblioteca de C # Excel para guardar archivos XLSB, pero también admite formatos de archivo XLS y XLSX.

Vea el siguiente ejemplo de código como alternativa de exportar DataGridView a Excel:

// Create a DataSet and add the DataTable of DataGridView DataSet dataSet = new DataSet(); dataSet.Tables.Add((DataTable)dataGridView); //or ((DataTable)dataGridView.DataSource).Copy() to create a copy // Export Excel file ExcelDocument workbook = new ExcelDocument(); workbook.easy_WriteXLSBFile_FromDataSet(filePath, dataSet, new EasyXLS.ExcelAutoFormat(EasyXLS.Constants.Styles.AUTOFORMAT_EASYXLS1), "Sheet1");

Si también necesita exportar el formato de DataGridView, consulte este ejemplo de código sobre cómo exportar datagridview a Excel en C # .


La interoperabilidad es lenta y tiene otros problemas, el uso del portapapeles parece no extensible. Aquí hay otras dos formas de hacer esto.

  1. Trabajar con Excel 2007+ directamente en lugar de trabajar con Excel, será mucho más rápido. Puede usar OpenXML ( http://openxmldeveloper.org/ ) que es el SDK de Microsoft. La mejor manera de aprender OpenXML es descargar la herramienta de productividad ( http://www.microsoft.com/en-us/download/details.aspx?id=5124) , toma un archivo existente y genera el código necesario para crearlo. . Otra opción, quizás más sencilla, es usar ClosedXML ( http://closedxml.codeplex.com/ ). Parece mucho más fácil de usar (mira el ejemplo http://closedxml.codeplex.com/wikipage?title=Showcase&referringTitle=Home ), pero no tengo experiencia con eso. Estoy seguro de que hay otras bibliotecas que envuelven el trabajo con Excel.

  2. Trabaja con excel vía OLEDB. Esto te permite trabajar con Excel como si fuera una base de datos. Consulte http://www.codeproject.com/Articles/8500/Reading-and-Writing-Excel-using-OLEDB o Performance of OLEDB para leer Excel para ver ejemplos y más detalles.

Yo empezaría con ClosedXML.


Lo mejor es usar el uso de la biblioteca closedxml.codeplex.com. Reemplácelo en https://closedxml.codeplex.com/wikipage?title=Adding%20DataTable%20as%20Worksheet&referringTitle=Documentation

var wb = new ClosedXML.Excel.XLWorkbook(); DataTable dt = GetTheDataTable();//Refer documentation wb.Worksheets.Add(dt); Response.Clear(); Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; Response.AddHeader("content-disposition", "attachment;filename=/"FileName.xlsx/""); using (var ms = new System.IO.MemoryStream()) { wb.SaveAs(ms); ms.WriteTo(Response.OutputStream); ms.Close(); } Response.End();


Me gusta la solución de Jake. El problema sin encabezado se resuelve haciendo lo siguiente

xlWorkSheet.Cells[1, 1] = "Header 1"; xlWorkSheet.Cells[1, 2] = "Header 2"; xlWorkSheet.Cells[1, 3] = "Header 3";

Por supuesto, esto solo funciona si sabes lo que los encabezados deben estar adelantados.


No tenía la intención de robar la respuesta de @Jake y @ Cornelius, así que intenté editarla. pero fue rechazado. De todos modos, la única mejora que debo señalar es sobre evitar la columna en blanco extra en Excel después de pegar. Agregando una línea dataGridView1.RowHeadersVisible = false; oculta el llamado "Encabezado de fila" que aparece en la parte más a la izquierda de DataGridView, por lo que no se selecciona ni se copia en el portapapeles cuando se realiza dataGridView1.SelectAll();

private void copyAlltoClipboard() { //to remove the first blank column from datagridview dataGridView1.RowHeadersVisible = false; dataGridView1.SelectAll(); DataObject dataObj = dataGridView1.GetClipboardContent(); if (dataObj != null) Clipboard.SetDataObject(dataObj); } private void button3_Click_1(object sender, EventArgs e) { copyAlltoClipboard(); Microsoft.Office.Interop.Excel.Application xlexcel; Microsoft.Office.Interop.Excel.Workbook xlWorkBook; Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet; object misValue = System.Reflection.Missing.Value; xlexcel = new Excel.Application(); xlexcel.Visible = true; xlWorkBook = xlexcel.Workbooks.Add(misValue); xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1]; CR.Select(); xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true); }


Resolví esto por simple método de copiar y pegar. No sé, es la mejor manera de hacer esto, pero para mí funciona bien y casi instantáneamente. Aquí está mi código.

private void copyAlltoClipboard() { dataGridView1.SelectAll(); DataObject dataObj = dataGridView1.GetClipboardContent(); if (dataObj != null) Clipboard.SetDataObject(dataObj); } private void button3_Click_1(object sender, EventArgs e) { copyAlltoClipboard(); Microsoft.Office.Interop.Excel.Application xlexcel; Microsoft.Office.Interop.Excel.Workbook xlWorkBook; Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet; object misValue = System.Reflection.Missing.Value; xlexcel = new Excel.Application(); xlexcel.Visible = true; xlWorkBook = xlexcel.Workbooks.Add(misValue); xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1]; CR.Select(); xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true); }

Gracias.


eso es lo que uso para mi vista de cuadrícula, trate de usarlo para los datos de su año, funciona perfectamente:

GridView1.AllowPaging = false; GridView1.DataBind(); StringBuilder sb = new StringBuilder(); for (int k = 0; k < GridView1.Columns.Count; k++) { //add separator sb.Append(GridView1.Columns[k].HeaderText+";"); } //append new line sb.Append("/r/n"); for (int i = 0; i < GridView1.Rows.Count; i++) { for (int k = 0; k < GridView1.Columns.Count; k++) { sb.Append(GridView1.Rows[i].Cells[k].Text+";"); } sb.AppendLine(); }


using Excel = Microsoft.Office.Interop.Excel; private void btnExportExcel_Click(object sender, EventArgs e) { try { Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application(); excel.Visible = true; Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Add(System.Reflection.Missing.Value); Microsoft.Office.Interop.Excel.Worksheet sheet1 = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[1]; int StartCol = 1; int StartRow = 1; int j = 0, i = 0; //Write Headers for (j = 0; j < dgvSource.Columns.Count; j++) { Microsoft.Office.Interop.Excel.Range myRange = (Microsoft.Office.Interop.Excel.Range)sheet1.Cells[StartRow, StartCol + j]; myRange.Value2 = dgvSource.Columns[j].HeaderText; } StartRow++; //Write datagridview content for (i = 0; i < dgvSource.Rows.Count; i++) { for (j = 0; j < dgvSource.Columns.Count; j++) { try { Microsoft.Office.Interop.Excel.Range myRange = (Microsoft.Office.Interop.Excel.Range)sheet1.Cells[StartRow + i, StartCol + j]; myRange.Value2 = dgvSource[j, i].Value == null ? "" : dgvSource[j, i].Value; } catch { ; } } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }