it-swarm.com.de

Wie exportiere ich dataGridView-Daten auf Knopfdruck sofort nach Excel?

Ich habe 10k Zeilen und 15 Spalten in meiner Datenrasteransicht. Ich möchte diese Daten in eine Excel-Tabelle exportieren. Ich habe es bereits mit dem folgenden Code versucht.

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

Dies funktioniert bei mir, aber es braucht viel Zeit, den Exportvorgang abzuschließen.

Ist es möglich, von DataGridView (mit 10k Zeilen) nach Excel sofort auf einen Knopfdruck zu exportieren?

Wenn ich versuchte, alle dataGridview-Inhalte in die Zwischenablage zu kopieren und sie dann manuell in ein Excel-Blatt einzufügen, passierte dies fast sofort.

Gibt es also eine Möglichkeit, alle dataGridView-Zellen in die Zwischenablage zu kopieren und auf Knopfdruck in eine Excel-Tabelle (mit Zellenformatierung) einzufügen?

Ich habe den folgenden Code zum Kopieren in die Zwischenablage, kann ihn jedoch nicht in ein neues Excel-Blatt einfügen, indem ich ihn öffne.

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

Bitte helfen Sie mit einem Beispiel. Ich bin neu in C #.

32
Jake

Ich löste dies durch einfaches Kopieren und Einfügen. Ich weiß nicht, dass dies der beste Weg ist, aber für mich funktioniert es fast sofort. Hier ist mein 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);          
    }

Vielen Dank.

56
Jake

Dies ist eine großartige Frage und ich war überrascht, wie schwierig es war, eine klare und vollständige Antwort zu finden. Die meisten Antworten, die ich fand, waren entweder Sudo-Code oder nicht 100% ig.

Ich konnte eine Komplettlösung erstellen, um die Daten aus meiner DataGridView in eine Excel-Datei zu kopieren und zu speichern, die auf Jakes Antwort basiert. Ich poste meine Komplettlösung in der Hoffnung, dass sie anderen Neulingen dabei helfen kann, c # wie ich zu sein :)

Zunächst benötigen Sie die Microsoft.Office.Interop.Excel-Referenz in Ihrem Projekt. Siehe MSDN zum Hinzufügen.

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

Ich hatte nicht vor, @Jake und die Antwort von Cornelius zu stehlen, also versuchte ich, sie zu bearbeiten. aber es wurde abgelehnt. Die einzige Verbesserung, die ich hervorheben muss, ist die Vermeidung zusätzlicher leerer Spalten in Excel nach dem Einfügen. Durch das Hinzufügen einer Zeile dataGridView1.RowHeadersVisible = false; wird der sogenannte "Row Header" ausgeblendet, der ganz links in DataGridView angezeigt wird. Er wird daher nicht ausgewählt und in die Zwischenablage kopiert, wenn Sie dataGridView1.SelectAll(); ausführen.

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

Am besten verwenden Sie 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();
3
Taran

Interop ist langsam und hat andere Probleme. Die Verwendung der Zwischenablage scheint nicht erweiterbar. Hier gibt es zwei weitere Möglichkeiten

  1. Arbeiten Sie direkt mit Excel 2007+ -Dateien, anstatt mit Excel zu arbeiten. Dies ist viel (viel) schneller. Sie können OpenXML ( http://openxmldeveloper.org/ ) verwenden, das das SDK von Microsoft ist. Der beste Weg, OpenXML zu erlernen, ist das Herunterladen des Produktivitätswerkzeugs ( http://www.Microsoft.com/de-de/download/details.aspx?id=5124) , es nimmt eine vorhandene Datei und generiert den Code erforderlich, um es zu erstellen. Eine andere, vielleicht einfachere Option ist die Verwendung von ClosedXML ( http://closedxml.codeplex.com/ ). Es scheint viel einfacher zu verwenden (siehe Beispiel http://closedxml.codeplex.com/wikipage?title=Showcase&referringTitle=Home ), aber ich habe keine Erfahrung damit. Ich bin mir sicher, dass es andere Bibliotheken gibt, die die Arbeit mit Excel abschließen.

  2. Arbeiten Sie mit Excel über OLEDB. Auf diese Weise können Sie mit Excel wie mit einer Datenbank arbeiten. Siehe http://www.codeproject.com/Articles/8500/Reading-and-Writing-Excel- using-OLEDB oder Leistung von OLEDB zum Lesen von Excel für Beispiele und weitere Einzelheiten.

Ich würde mit ClosedXML beginnen.

3
Vadim

Ich mag Jakes Lösung. Das Problem ohne Header wird folgendermaßen gelöst

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

natürlich funktioniert das nur, wenn Sie wissen, was die Header im Voraus sein sollten. 

2
jlh3302

das ist was ich für mein Gridview verwende, versuche es für eure Daten zu verwenden, es funktioniert perfekt: 

        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
Loubna H

Diese Antwort ist für die erste Frage, warum dies so lange dauert, und bietet eine alternative Lösung für den Export der DataGridView nach Excel. 

MS Office Interop ist langsam und sogar Microsoft empfiehlt die Verwendung von Interop auf dem Server nicht und kann nicht zum Exportieren großer Excel-Dateien verwendet werden. Weitere Informationen finden Sie unter Warum sollten Sie OLE - Automatisierung nicht aus Microsoft-Sicht verwenden?.

Interop speichert Excel-Dateien im XLS-Dateiformat (altes Excel 97-2003-Dateiformat) und die Unterstützung für Office 2003 ist beendet. Microsoft Excel hat das XLSX-Dateiformat mit Office 2007 veröffentlicht und empfiehlt die Verwendung von OpenXML SDK anstelle von Interop. XLSX-Dateien sind jedoch nicht so schnell und verarbeiten große Excel-Dateien nicht gut, da sie auf dem XML-Dateiformat basieren. Aus diesem Grund hat Microsoft auch das XLSB-Dateiformat mit Office 2007 veröffentlicht. Dieses Dateiformat wird für große Excel-Dateien empfohlen. Es ist ein binäres Format. Die beste und schnellste Lösung ist das Speichern von XLSB-Dateien.

Sie können diese C # Excel-Bibliothek verwenden, um XLSB-Dateien zu speichern, es werden jedoch auch XLS- und XLSX-Dateiformate unterstützt. 

Sehen Sie sich das folgende Codebeispiel als Alternative zum Exportieren von DataGridView nach Excel an:

// 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");

Wenn Sie auch die Formatierung der DataGridView-Datei exportieren müssen, überprüfen Sie dieses Codebeispiel, wie Sie datagridview in C # nach Excel exportieren.

1
alex.pulver

Diese Zeile funktioniert nur für das DataGridView-Steuerelement in Windows Forms:

DataObject dataObj = dataGridView1.GetClipboardContent();

In diesem Abschnitt wird das gleiche Problem behandelt, jedoch für das DataGrid-Steuerelement für das 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);
    }
0
George

Wenn in Ihrer DataGridView RightToLeft auf Yes eingestellt ist, werden Ihre Daten umgekehrt kopiert. Verwenden Sie daher den folgenden Code, um die Daten korrekt zu kopieren.

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

alternativ Sie können einen schnellen Export durchführen, ohne Office-DLL zu verwenden, da Excel CSV-Dateien ohne Probleme analysieren kann.

So etwas tun (für weniger als 65.536 Zeilen mit Titeln):

  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
0
Caveman