C# 导入大的.xlsx文件非常慢

C# 导入大的.xlsx文件非常慢,c#,wpf,excel,datagrid,wpfdatagrid,C#,Wpf,Excel,Datagrid,Wpfdatagrid,我是c#和WPF的新手,尝试将一个大的.xlsx文件导入到datagrid中,我可以拥有200多列和100000多行。以我目前的方法,它需要一个多小时(我没有让它完成)。我的csv格式的一个例子是 "Time","Dist","V_Front","V_Rear","RPM" "s","m","km/h","km/h","rpm" "0.000","0","30.3","30.0","11995" "0.005","0","30.3","30.0","11965" "0.010","0","30.

我是c#和WPF的新手,尝试将一个大的.xlsx文件导入到datagrid中,我可以拥有200多列和100000多行。以我目前的方法,它需要一个多小时(我没有让它完成)。我的csv格式的一个例子是

"Time","Dist","V_Front","V_Rear","RPM"
"s","m","km/h","km/h","rpm"
"0.000","0","30.3","30.0","11995"
"0.005","0","30.3","30.0","11965"
"0.010","0","30.3","31.0","11962"
目前我正在使用互操作,但我想知道是否有另一种方法可以大幅缩短加载时间。我希望使用SciCharts(他们有学生执照)绘制这些数据,并带有频道选择复选框,但那是另一回事

.CS

private void按钮\u单击(对象发送者,路由目标)
{
OpenFileDialog openfile=新建OpenFileDialog();
openfile.DefaultExt=“.xlsx”;
openfile.Filter=“(.xlsx)|*.xlsx”;
var browsefile=openfile.ShowDialog();
if(browsefile==true)
{
txtFilePath.Text=openfile.FileName;
Microsoft.Office.Interop.Excel.Application excelApp=新的Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook excelBook=excelApp.Workbooks.Open(txtFilePath.Text.ToString(),0,true,5,“,”,true,Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,“\t”,false,false,0,true,1,0);
Microsoft.Office.Interop.Excel.Worksheet excelSheet=(Microsoft.Office.Interop.Excel.Worksheet)excelBook.Worksheets.get_项(1);
Microsoft.Office.Interop.Excel.Range excelRange=excelSheet.UsedRange;
字符串strCellData=“”;
双双细胞数据;
int rowCnt=0;
int colCnt=0;
DataTable dt=新的DataTable();

对于(colCnt=1;colCnt问题是单个读取太多,这会导致Excel和应用程序之间的大量反射使用和编组。如果您不关心内存使用情况,您可以将整个
范围
读入内存并从内存中工作,而不是单独读取单元格。下面的代码在一个包含5列和103938行的测试文件上,ns为3880毫秒:

OpenFileDialog openfile = new OpenFileDialog();
openfile.DefaultExt = ".xlsx";
openfile.Filter = "(.xlsx)|*.xlsx";

var browsefile = openfile.ShowDialog();

if (browsefile == true)
{
    txtFilePath.Text = openfile.FileName;

    var excelApp = new Microsoft.Office.Interop.Excel.Application();
    var excelBook = excelApp.Workbooks.Open(txtFilePath.Text, 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 dt = new DataTable();

    object[,] value = excelRange.Value;

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

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

    dtGrid.ItemsSource = dt.DefaultView;

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

处理程序只调用解析函数,解析函数在后台线程上运行,当它完成时,处理程序可以通过将生成的
DataTable
分配给
ItemsSource

来继续,而不是单独插入每一行,将其全部放入c的
列表中可能会更快ustom对象,可以进行数据绑定。您可能希望使用
StringBuilder
s,因为您对字符串进行了大量操作。您是否尝试使用OLEDB填充数据表?DiskJunky您的意思是我应该将列加载到单独的列表中还是一个大列表中?Equalsk-不,我现在将研究它。谢谢Sequalsk-我在程序中有OLEDB但是,ram现在得到:System.InvalidOperationException:“Microsoft.ACE.OLEDB.12.0”提供程序未在本地计算机上注册。谢谢,这很有意义。您能解释一下在后台线程上运行此提供程序的更多信息吗?干杯
OpenFileDialog openfile = new OpenFileDialog();
openfile.DefaultExt = ".xlsx";
openfile.Filter = "(.xlsx)|*.xlsx";

var browsefile = openfile.ShowDialog();

if (browsefile == true)
{
    txtFilePath.Text = openfile.FileName;

    var excelApp = new Microsoft.Office.Interop.Excel.Application();
    var excelBook = excelApp.Workbooks.Open(txtFilePath.Text, 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 dt = new DataTable();

    object[,] value = excelRange.Value;

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

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

    dtGrid.ItemsSource = dt.DefaultView;

    excelBook.Close(true);
    excelApp.Quit();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog openfile = new OpenFileDialog();
    openfile.DefaultExt = ".xlsx";
    openfile.Filter = "(.xlsx)|*.xlsx";

    var browsefile = openfile.ShowDialog();

    if (browsefile == true)
    {
        txtFilePath.Text = openfile.FileName;

        DataTable dataTable = await ParseExcel(txtFilePath.Text).ConfigureAwait(true);

        dtGrid.ItemsSource = dataTable.DefaultView;
    }
}

private 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 dt = new DataTable();

        object[,] value = excelRange.Value;

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

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

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

        return dt;
    });
}