1
votes

Exportation Excel Fast DataGrid

En utilisant une grille de données affichant beaucoup d'informations, toujours plus de 10 000 lignes jusqu'à un million de lignes avec 5 ou 6 colonnes. Je veux avoir un bouton sur mon application WPF qui exporte ces données vers un fichier Excel, en conservant la même structure de colonnes.

J'utilise MicrosoftOffice - Interop =, cependant, cela prend beaucoup de temps. Existe-t-il un moyen plus rapide d'y parvenir?

Merci,

Ma classe d'aide à l'exportation Excel:

public static DataTable ConvertToDataTable<T>(IList<T> data)
{
    var properties = TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new System.Data.DataTable();
    foreach (PropertyDescriptor prop in properties)
    {
        table.Columns.Add(prop.Name, 
            Nullable.GetUnderlyingType(prop.PropertyType) ?? 
            prop.PropertyType);
    }
    foreach (T item in data)
    {
        DataRow row = table.NewRow();
        foreach (PropertyDescriptor prop in properties)
        {
            row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
        }
        table.Rows.Add(row);
    }
    return table;
}

public static void ExportToExcel(DataTable tbl, ProgressDialogController dialogController, string excelFilePath = null)
{
    try
    {
        if (tbl == null || tbl.Columns.Count == 0)
            throw new Exception("ExportToExcel: Null or empty input table!\n");
        // load excel, and create a new workbook
        var excelApp = new Microsoft.Office.Interop.Excel.Application();
        excelApp.Workbooks.Add();
        // single worksheet
        Microsoft.Office.Interop.Excel._Worksheet workSheet = excelApp.ActiveSheet;
        // column headings
        for (var i = 0; i < tbl.Columns.Count; i++)
        {
            workSheet.Cells[1, i + 1] = tbl.Columns[i].ColumnName;
            if(dialogController.IsCanceled)
            {
                return;                        
            }
        }
        // rows
        for (var i = 0; i < tbl.Rows.Count; i++)
        {
            // to do: format datetime values before printing
            for (var j = 0; j < tbl.Columns.Count; j++)
            {
                workSheet.Cells[i + 2, j + 1] = tbl.Rows[i][j];
            }
            dialogController.SetProgress((double)i / tbl.Rows.Count);
            if (dialogController.IsCanceled)
            {
                return;
            }
        }
        // check file path
        if (!string.IsNullOrEmpty(excelFilePath))
        {
            try
            {
                // workSheet.SaveAs(excelFilePath);
                workSheet.SaveAs(excelFilePath, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook, Missing.Value,
                    Missing.Value, false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
                    Microsoft.Office.Interop.Excel.XlSaveConflictResolution.xlUserResolution, true,
                    Missing.Value);
                excelApp.Quit();
            }
            catch (Exception ex)
            {
                throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n" + ex.Message);
            }
        }
        else
        { // no file path is given
            excelApp.Visible = true;
        }
    }
    catch (Exception ex)
    {
        throw new Exception("ExportToExcel: \n" + ex.Message);
    }
}


3 commentaires

Toutes ces données sont disponibles sur SQL Table. Serait-il possible de le coder pour l'exporter directement de SQL TABLE vers Excel?


N'essayez pas de faire cela cellule par cellule - cela prendra une éternité (comme vous l'avez déjà vu ...) Créez un tableau 2D et écrivez-le sur la feuille en une seule opération.


stackoverflow.com/questions/536636/write-array-to -excel-rang‌ e


3 Réponses :


0
votes

Au lieu de Microsoft Interop, vous pouvez utiliser le SDK Open XML pour créer des fichiers Excel. L'interopérabilité est plus lente et nécessite l'installation de l'application Excel. L'Open XML est plus rapide et ne nécessite pas l'application Excel.

Consultez ces exemples de Microsoft:

https://docs.microsoft.com/en-us/office/open-xml/how-to-create-a-spreadsheet-document-by-providing-a-file-name

https://docs.microsoft.com/en-us/office/open-xml/how-to-insert-text-into-a-cell-in-a-spreadsheet


0 commentaires

0
votes
      //very simple method without external any DLL
      //dg is Datagrid 
      {
        string Destination = ".\.....location\_filename.xls";
        dg.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
        dg.SelectAllCells();


        ApplicationCommands.Copy.Execute(null, dg);
        String resultat = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
        String result = (string)Clipboard.GetData(DataFormats.Text);
        //dg.UnselectAllCells();
        System.IO.StreamWriter file1 = new System.IO.StreamWriter(Destination);
        file1.WriteLine(result.Replace(',', ' '));
        file1.Close();
       }

0 commentaires

0
votes

Appréciez toutes les réponses les gars!

Les deux solutions semblent fonctionner correctement et plus rapidement que ma première solution. Cependant, après quelques recherches supplémentaires, j'ai trouvé que beaucoup de gens utilisent EPPlus, non seulement c'est rapide, mais il fonctionnera sur n'importe quel ordinateur même si Excel n'est pas installé. Et bien plus simple que les solutions ci-dessus.

Salut! https://github.com/JanKallman/EPPlus Exporter DataTable vers Excel avec EPPlus Comment créer un fichier Excel (.XLS et .XLSX) en C # sans installer Microsoft Office?


0 commentaires