[c#] How to export dataGridView data Instantly to Excel on button click?

I have 10k rows and 15 column in my data grid view. I want to export this data to an excel sheet o button click. I have already tried with the below code.

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] = "";
                }
            }
        }
    }

This is working for me but it is taking lots of time to complete exporting process.

Is it possible to export from dataGridView (with 10k rows)to excel instantly on a button click?

Other than this, when I tried copy all dataGridview contents to clip board and then paste it to excel sheet manually, it happen almost instantly.

So is there a way to copy all dataGridView cells to clip board and paste it to excel sheet(with cell formatting) on a button click?

I have code for copy to clipboard as below, but I don't know how to paste it in to a new excel sheet by opening it.

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

Please help with an example. I am new to C#.

This question is related to c# datagridview copy export-to-excel export-to-csv

The answer is


If your DataGridView's RightToLeft set to Yes then your data copy reversely. So you should use the below code to copy the data correctly.

private void copyAlltoClipboard()
{
    dgvItems.RightToLeft = RightToLeft.No;
    dgvItems.SelectAll();
    DataObject dataObj = dgvItems.GetClipboardContent();
    if (dataObj != null)
        Clipboard.SetDataObject(dataObj);
    dgvItems.RightToLeft = RightToLeft.Yes;
}

The Best is use use closedxml.codeplex.com Library.Refer it @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();

This line works only for the DataGridView Control on Windows Forms:

DataObject dataObj = dataGridView1.GetClipboardContent();

This one addresses the same issue, but for the DataGrid control for the WPF Framework:

    private void copyDataGridContentToClipboard()
    {
        datagridGrupeProductie.SelectAll();
        datagridGrupeProductie.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;

        ApplicationCommands.Copy.Execute(null, datagridGrupeProductie);
        datagridGrupeProductie.UnselectAll();
    }


    private void rightClickGrupeProductie_Click(object sender, RoutedEventArgs e)
    {
        copyDataGridContentToClipboard();
        Microsoft.Office.Interop.Excel.Application excelApp;
        Microsoft.Office.Interop.Excel.Workbook excelWkbk;
        Microsoft.Office.Interop.Excel.Worksheet excelWksht;
        object misValue = System.Reflection.Missing.Value;
        excelApp = new Microsoft.Office.Interop.Excel.Application();
        excelApp.Visible = true;
        excelWkbk = excelApp.Workbooks.Add(misValue);
        excelWksht = (Microsoft.Office.Interop.Excel.Worksheet)excelWkbk.Worksheets.get_Item(1);
        Microsoft.Office.Interop.Excel.Range CR = (Microsoft.Office.Interop.Excel.Range)excelWksht.Cells[1, 1];
        CR.Select();
        excelWksht.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true);
    }

I did not intend to steal @Jake and @Cornelius's answer, so i tried editing it. but it was rejected. Anyways, the only improvement I have to point out is about avoiding extra blank column in excel after paste. Adding one line dataGridView1.RowHeadersVisible = false; hides so called "Row Header" which appears on the left most part of DataGridView, and so it is not selected and copied to clipboard when you do 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);          
    }

I'm adding this answer because none of the other methods use OpenXMLWriter, despite the fact that it is faster than OpenXML DOM and both faster and more reliable than COM/Interop, and because some of the other methods use the clipboard, which I would caution against, as it's output is unreliable.

The details can be found in my answer in the link below, however that example is for a DataTable, but you can adapt it to using a DataGridView by just changing the row/column loops to reference a dgv instead of a dt.

How to export DataTable to Excel


This answer is for the first question, why it takes so much time and it offers an alternative solution for exporting the DataGridView to Excel.

MS Office Interop is slow and even Microsoft does not recommend Interop usage on server side and cannot be use to export large Excel files. For more details see why not to use OLE Automation from Microsoft point of view.

Interop saves Excel files in XLS file format (old Excel 97-2003 file format) and the support for Office 2003 has ended. Microsoft Excel released XLSX file format with Office 2007 and recommends the usage of OpenXML SDK instead of Interop. But XLSX files are not really so fast and doesn’t handle very well large Excel files because they are based on XML file format. This is why Microsoft also released XLSB file format with Office 2007, file format that is recommended for large Excel files. It is a binary format. So the best and fastest solution is to save XLSB files.

You can use this C# Excel library to save XLSB files, but it also supports XLS and XLSX file formats.

See the following code sample as alternative of exporting DataGridView to 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");

If you also need to export the formatting of the DataGridView check this code sample on how to export datagridview to Excel in C#.


I like Jake's solution. The problem with no header is resolved by doing the following

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

of course this only works is you know what the headers should be ahead of time.


that's what i use for my gridview, try to use it for yr data , it works perfectly :

        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());
    }
}

In my opinion this is the easiest and instantly working method of exporting datagridview.

 try
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Excel Documents (*.xlsx)|*.xlsx";
            sfd.FileName = "ProfitLoss.xlsx";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                DataTable dts = new DataTable();
                for (int i = 0; i < grdProfitAndLoss.Columns.Count; i++)
                {
                    dts.Columns.Add(grdProfitAndLoss.Columns[i].Name);
                }
                for (int j = 0; j < grdProfitAndLoss.Rows.Count; j++)
                {
                    DataRow toInsert = dts.NewRow();
                    int k = 0;
                    int inc = 0;
                    for (k = 0; k < grdProfitAndLoss.Columns.Count; k++)
                    {
                        if (grdProfitAndLoss.Columns[k].Visible == false) { continue; }
                        toInsert[inc] = grdProfitAndLoss.Rows[j].Cells[k].Value;
                        inc++;
                    }
                    dts.Rows.Add(toInsert);
                }
                dts.AcceptChanges();
                ExcelUtlity obj = new ExcelUtlity();
                obj.WriteDataTableToExcel(dts, "Profit And Loss", sfd.FileName, "Profit And Loss");
                MessageBox.Show("Exported Successfully");
            }
        }
        catch (Exception ex)
        {

        }

This is a great question and I was surprised at how difficult it was to find a clear and complete answer, most of the answers I found were either sudo-code or not 100% complete.

I was able to create a complete solution to copy and save the data from my DataGridView to an excel file based on Jake's answer so I'm posting my complete solution in the hopes that it can help other new comers to c# like myself :)

First off, you will need the Microsoft.Office.Interop.Excel reference in your project. See MSDN on how to add it.

My Code:

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();
    }
}

Interop is slow and has other issues, using the the clipboard seems non extensible. Here are two other ways to do this

  1. Work with Excel 2007+ files directly instead of working with Excel, it'll be much (much) faster. You can use OpenXML (http://openxmldeveloper.org/) which is Microsoft's SDK. The best way to learn OpenXML is to download the Productivity tool (http://www.microsoft.com/en-us/download/details.aspx?id=5124), ittakes an existing file and generates the code required to create it. Another, perhaps simpler, option is to use ClosedXML (http://closedxml.codeplex.com/). It seems a lot easier to use (look at the example http://closedxml.codeplex.com/wikipage?title=Showcase&referringTitle=Home), but I have no experience with it. I'm sure there are other libraries that wrap work with Excel.

  2. Work with excel via OLEDB. This allows you to work with Excel as if it's a dababase. See http://www.codeproject.com/Articles/8500/Reading-and-Writing-Excel-using-OLEDB or Performance of OLEDB to read Excel for examples and more details.

I'd start with ClosedXML.


alternatively you can perform a fast export without using Office dll, as Excel can parse csv files without problems.

Doing something like this (for less than 65.536 rows with titles):

  Try

            If (p_oGrid.RowCount = 0) Then
                MsgBox("No data", MsgBoxStyle.Information, "App")
                Exit Sub
            End If

            Cursor.Current = Cursors.WaitCursor

            Dim sText As New System.Text.StringBuilder
            Dim sTmp As String
            Dim aVisibleData As New List(Of String)

            For iAuxRow As Integer = 0 To p_oGrid.Columns.Count - 1
                If p_oGrid.Columns(iAuxRow).Visible Then
                    aVisibleData.Add(p_oGrid.Columns(iAuxRow).Name)
                    sText.Append(p_oGrid.Columns(iAuxRow).HeaderText.ToUpper)
                    sText.Append(";")
                End If
            Next
            sText.AppendLine()

            For iAuxRow As Integer = 0 To p_oGrid.RowCount - 1
                Dim oRow As DataGridViewRow = p_oGrid.Rows(iAuxRow)
                For Each sCol As String In aVisibleData
                    Dim sVal As String
                    sVal = oRow.Cells(sCol).Value.ToString()
                    sText.Append(sVal.Replace(";", ",").Replace(vbCrLf, " ; "))
                    sText.Append(";")
                Next
                sText.AppendLine()
            Next

            sTmp = IO.Path.GetTempFileName & ".csv"
            IO.File.WriteAllText(sTmp, sText.ToString, System.Text.Encoding.UTF8)
            sText = Nothing

            Process.Start(sTmp)

        Catch ex As Exception
            process_error(ex)
        Finally
            Cursor.Current = Cursors.Default
        End Try

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to datagridview

How to refresh or show immediately in datagridview after inserting? Delete a row in DataGridView Control in VB.NET Looping each row in datagridview How to get cell value from DataGridView in VB.Net? Changing datagridview cell color based on condition Index was out of range. Must be non-negative and less than the size of the collection parameter name:index how to bind datatable to datagridview in c# DataGridView AutoFit and Fill How to export dataGridView data Instantly to Excel on button click? Populate a datagridview with sql query results

Examples related to copy

Copying files to a container with Docker Compose Copy filtered data to another sheet using VBA Copy output of a JavaScript variable to the clipboard Dockerfile copy keep subdirectory structure Using a batch to copy from network drive to C: or D: drive Copying HTML code in Google Chrome's inspect element What is the difference between `sorted(list)` vs `list.sort()`? How to export all data from table to an insertable sql format? scp copy directory to another server with private key auth How to properly -filter multiple strings in a PowerShell copy script

Examples related to export-to-excel

Export from pandas to_excel without row names (index)? How to export dataGridView data Instantly to Excel on button click? How to export a CSV to Excel using Powershell How to create an Excel File with Nodejs? Download Excel file via AJAX MVC Export data to Excel file with ASP.NET MVC 4 C# is rendering into view Saving results with headers in Sql Server Management Studio phpexcel to download Export SQL query data to Excel How can I export tables to Excel from a webpage

Examples related to export-to-csv

Excel: macro to export worksheet as CSV file without leaving my current Excel sheet Export to csv/excel from kibana How to export data from Spark SQL to CSV How to export a table dataframe in PySpark to csv? Java - Writing strings to a CSV file How to export dataGridView data Instantly to Excel on button click? Export javascript data to CSV file without server interaction How to create and download a csv file from php script? Export to CSV using jQuery and html export html table to csv