Excel Fast DataGrid Export - PullRequest
       1

Excel Fast DataGrid Export

0 голосов
/ 04 октября 2019

Используя сетку данных, отображающую много информации, всегда более 10 000 строк до миллиона строк с 5 или 6 столбцами. Я хочу, чтобы в моем приложении WPF была кнопка, которая экспортирует эти данные в файл Excel, сохраняя ту же структуру столбцов.

Я использую MicrosoftOffice - Interop =, однако для этого требуется много времени. Есть ли более быстрый способ добиться этого?

Спасибо,

My Excel Export Helper Class:

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 ]

0 голосов
/ 11 октября 2019
      //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 голосов
/ 15 октября 2019

Оцените все ответы, ребята!

Кажется, что оба решения работают нормально и быстрее, чем мое первое решение. Однако после некоторых дополнительных исследований я обнаружил, что многие люди используют EPPlus не только быстро, но и будут работать на любом компьютере, даже если у вас не установлен Excel. Плюс гораздо проще, чем приведенные выше решения.

Ура! https://github.com/JanKallman/EPPlus Экспорт DataTable в Excel с EPPlus Как создать файл Excel (.XLS и .XLSX) в C # без установки Microsoft Office?

0 голосов
/ 04 октября 2019

Вместо Microsoft Interop вы можете использовать Open XML SDK для создания файлов Excel. Взаимодействие медленнее и требует установки приложения Excel. Открыть XML быстрее и не требует приложения Excel.

Посмотрите эти примеры от 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...