Comment exporter des données dataGridView instantanément pour exceller sur le bouton cliquez?

j'ai 10k lignes et 15 colonne dans ma vue de grille de données. Je veux exporter ces données à un clic de feuille d'excel. J'ai déjà essayé avec le code ci-dessous.

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

cela fonctionne pour moi mais cela prend beaucoup de temps pour processus d'exportation complet.

est-il possible d'exporter de dataGridView (avec des lignes de 10k)pour exceller instantanément sur un clic de bouton?

En dehors de cela, quand j'ai essayé de copier tous les contenus de dataGridview à la planche de clip et puis le coller à la feuille d'excel manuellement, cela se produit presque instantanément.

alors y a-t-il un moyen de copier toutes les cellules de dataGridView pour clipper le panneau et le coller à la feuille excel(avec le formatage de cellules) sur un clic de bouton?

j'ai le code pour copier au bloc-notes comme ci-dessous, mais je ne sais pas comment le coller dans une nouvelle feuille excel en l'ouvrant.

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

s'il vous Plaît aider avec un exemple. Je suis nouveau en C#.

29
demandé sur Jake 2013-08-12 11:59:46

9 réponses

j'ai résolu cela par la méthode de la copie simple et de la pâte. Je ne sais pas qu'elle est la meilleure façon de le faire, mais,pour moi, il fonctionne bien, et presque instantanément. Voici mon code.

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

Merci.

54
répondu Jake 2013-08-12 19:19:07

c'est une excellente question et j'ai été surpris à quel point il était difficile de trouver une réponse claire et complète, la plupart des réponses que j'ai trouvées étaient soit sudo-code ou pas 100% complet.

j'ai été en mesure de créer une solution complète pour copier et enregistrer les données de mon DataGridView à un fichier excel basé sur la réponse de Jake donc je poste ma solution complète dans l'espoir qu'il peut aider d'autres nouveaux venus à c# comme moi:)

tout d'abord, vous allez besoin de la référence Microsoft.Office.Interop.Excel dans votre projet. Voir MSDN sur la façon de l'ajouter.

Mon 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();
    }
}
17
répondu Cornelius 2015-07-14 16:46:07

Je n'avais pas l'intention de voler la réponse de @Jake et @Cornelius, alors j'ai essayé de l'éditer. mais il a été rejeté. Quoi qu'il en soit, la seule amélioration que je dois souligner est d'éviter la colonne vide supplémentaire dans excel après la pâte. L'ajout d'une ligne dataGridView1.RowHeadersVisible = false; cache ce qu'on appelle "L'en-tête de ligne" qui apparaît sur la partie gauche de DataGridView, et donc il n'est pas sélectionné et copié sur le bloc-notes quand vous faites 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);          
    }
6
répondu Рахул Маквана 2016-07-20 20:39:23
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());
    }
}
5
répondu Koray 2017-04-07 05:05:14

Interop est lent et a d'autres problèmes, en utilisant le bloc-notes semble non extensible. Voici deux autres façons de le faire

  1. travailler avec Excel 2007+ fichiers directement au lieu de travailler avec Excel, ce sera beaucoup (beaucoup) plus rapide. Vous pouvez utiliser OpenXML ( http://openxmldeveloper.org / ) qui est le SDK de Microsoft. La meilleure façon D'apprendre OpenXML est de télécharger L'outil de productivité ( http://www.microsoft.com/en-us/download/details.aspx?id=5124) , il crée un fichier existant et génère le code requis pour le créer. Une autre option, peut-être plus simple, est D'utiliser ClosedXML ( http://closedxml.codeplex.com / ). Il semble beaucoup plus facile à utiliser (voir l'exemple http://closedxml.codeplex.com/wikipage?title=Showcase&referringTitle=Home ), mais je n'en ai aucune expérience. Je suis sûr qu'il ya d'autres bibliothèques qui enveloppent travail avec Excel.

  2. travail avec excel via OLEDB. Cela vous permet de travailler avec Excel comme si c'était une base de données. Voir http://www.codeproject.com/Articles/8500/Reading-and-Writing-Excel-using-OLEDB ou la Performance de OLEDB pour lire Excel pour des exemples et plus de détails.

je commencerais par ClosedXML.

3
répondu Vadim 2017-05-23 11:54:59

le meilleur est d'utiliser closedxml.codeplex.com Bibliothèque.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();
3
répondu Taran 2015-07-27 20:14:43

j'aime la solution de Jake. Le problème avec NO header est résolu en faisant ce qui suit

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

bien sûr, cela ne fonctionne que vous savez ce que les en-têtes devraient être à l'avance.

2
répondu jlh3302 2014-06-13 20:28:47

c'est ce que j'utilise pour mon gridview, essayer de l'utiliser pour les données yr , ça marche parfaitement:

        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();
        }
1
répondu Loubna H 2013-08-12 08:15:18

cette réponse est pour la première question, pourquoi cela prend tant de temps et il offre une solution alternative pour exporter le DataGridView vers Excel.

MS Office Interop est lent et même Microsoft ne recommande pas L'utilisation D'Interop côté serveur et ne peut pas être utilisé pour exporter de grands fichiers Excel. Pour plus de détails voir pourquoi ne pas utiliser OLE Automation du point de vue de Microsoft.

Interop sauve des fichiers Excel dans le fichier XLS format (ancien format de fichier Excel 97-2003) et le support pour Office 2003 est terminé. Microsoft Excel a publié le format de fichier XLSX avec Office 2007 et recommande L'utilisation D'OpenXML SDK au lieu D'Interop. Mais les fichiers XLSX ne sont pas vraiment si rapides et ne gèrent pas très bien les grands fichiers Excel parce qu'ils sont basés sur le format de fichier XML. C'est pourquoi Microsoft a également publié le format de fichier XLSB avec Office 2007, format de fichier qui est recommandé pour les grands fichiers Excel. C'est un format binaire. Donc, la meilleure et la solution la plus rapide est d'enregistrer des fichiers XLSB.

vous pouvez utiliser ce c# Excel library pour enregistrer des fichiers XLSB, mais il prend également en charge les formats de fichiers XLS et XLSX.

voir l'exemple de code suivant comme alternative à l'exportation de DataGridView vers 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 vous avez aussi besoin d'exporter le formatage de DataGridView cochez cet exemple de code sur la façon de exporter datagridview pour exceller en C# .

1
répondu alex.pulver 2014-11-25 10:53:11