c# wpf 导入 excel 性能

c# wpf importing excel performance

我正在导入一个大的 excel 文件,该文件的长度可以变化(250 多列 * 100,000 行),它包含数据列,其中列的数量及其名称可以更改,行也是变量,但它们是值。

我正在使用 Interop 将数据提取到绑定到数据网格的数据表中,但是我正在单独导入每一行,对于较大的文件可能需要 25 分钟以上的时间才能完成。

    public Task<DataTable> ParseExcel(string filePath)
    {
        return Task.Run(() =>
        {
            var excelApp = new Microsoft.Office.Interop.Excel.Application();
            var excelBook = excelApp.Workbooks.Open(filePath, 0, true, 5, "", "", true,
                Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
            var excelSheet = (Microsoft.Office.Interop.Excel.Worksheet)excelBook.Worksheets.Item[1];

            Microsoft.Office.Interop.Excel.Range excelRange = excelSheet.UsedRange;

            DataTable sessiondt = new DataTable();

            object[,] value = excelRange.Value;

            int columnsCount = value.GetLength(1);
            for (var colCnt = 1; colCnt <= columnsCount; colCnt++)
            {
                sessiondt.Columns.Add((string)value[1, colCnt], typeof(string));
            }

            int rowsCount = value.GetLength(0);
            for (var rowCnt = 2; rowCnt <= rowsCount; rowCnt++)
            {
                var dataRow = sessiondt.NewRow();
                for (var colCnt = 1; colCnt <= columnsCount; colCnt++)
                {
                    dataRow[colCnt - 1] = value[rowCnt, colCnt];
                }
                sessiondt.Rows.Add(dataRow);
            }

            excelBook.Close(true);
            excelApp.Quit();

            return sessiondt;
        });  
    }

与其单独插入每一行,不如将其全部放入可以绑定数据的自定义对象的列表中可能会更快。但我不确定该怎么做。

另外,我想以一种不需要提前在列名中编码的方式绑定列。我将尝试在图表中显示这些,并且能够自动将列名填充到组合框中会更容易。

提前谢谢你,我是 c# 和 wpf 的新手,还在学习中。

Interop 有一些特定用途,但如果您只想从 Excel 文件中获取数据,Interop 可能是最慢、最麻烦的方法。

Excel 文件,无论是 .xls 还是 .xlsx 都可以像数据库一样处理和访问。

只要您的工作sheets 中的行和列中有数据,您就可以打开到它的OleDb 连接并运行 查询它。

Sheet 名称代替了 table 名称,如果您在 sheet 的第一行中有列标题,那么这些就是字段名称。

您只需要正确的连接字符串: https://www.connectionstrings.com/excel/

使用这种方法检索数据的 'watch-outs' 之一是数据类型是根据每列中的前几个条目自动分配的。您无法覆盖此行为(您曾经可以,但现在不能)。如果您在一列中有 alpha-numerics,并且前十几个条目都是数字,这可能会导致问题。然后该列将自动分配为数字类型。如果您在该列后面的行中有混合 alpha-numeric 或纯文本的数据,这些条目将被忽略(不导入),因为它们与最初分配的数据类型不匹配。

解决此问题的唯一好方法是以编程方式解压缩并解析 xml 文件的内容。

如果您始终拥有一致的数据,那么这不是问题。

这是使用 GemBox.Spreadsheet 库实现此目的的另一种方法,既快速又直接:

public Task<DataTable> ParseExcel(string filePath)
{
    return Task.Run(() =>
    {
        ExcelFile excelBook = ExcelFile.Load(filePath);
        ExcelWorksheet excelSheet = excelBook.Worksheets[0];

        CreateDataTableOptions options = new CreateDataTableOptions();
        return excelSheet.CreateDataTable(options);
    });
}

同时检查 this DataTable from Sheet example