Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 高效地插入行+数据_C#_Excel_Excel Interop - Fatal编程技术网

C# 高效地插入行+数据

C# 高效地插入行+数据,c#,excel,excel-interop,C#,Excel,Excel Interop,我有一个excel,它有上万行。我需要在此excel中随机插入数据。下面是我现在使用的功能,主要关注的是移位和插入数据。我需要一个更好的想法或方法,可以做同样的我,但更快 一个好的答案将有希望展示一个方法和注释来解释它是如何工作的。因此,如果其他人需要它,它可以被重用 这是我的: private void shiftRows(int from, int numberof) { from++; Range r = oXL.get_Range("A"

我有一个excel,它有上万行。我需要在此excel中随机插入数据。下面是我现在使用的功能,主要关注的是移位和插入数据。我需要一个更好的想法或方法,可以做同样的我,但更快

一个好的答案将有希望展示一个方法和注释来解释它是如何工作的。因此,如果其他人需要它,它可以被重用

这是我的:

    private void shiftRows(int from, int numberof)
    {
        from++;
        Range r = oXL.get_Range("A" + from.ToString(), "A" + from.ToString()).EntireRow;

        for (int i = 0; i < numberof; i++)
            r.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftDown);
    }

    public void inputRowData(string[] data, int rds)
    {
        int bestRow = getRowByRDS_a(rds);
        string[] formatedData = formatOutput(bestRow, data);
        string val = getValueOfCell(bestRow, 6);
        if (val != null)
        {
            shiftRows(bestRow, data.Length);
            bestRow++;
        }
        else
            shiftRows(bestRow, data.Length - 1);
        // transform formated data into string[,]
        string[][] splitedData = formatedData.Select(s => s.Split('\t')).ToArray();
        var colCount = splitedData.Max(r => r.Length);
        var excelData = new string[splitedData.Length, colCount];
        for (int i = 0; i < splitedData.Length; i++)
        {
            for (int j = 0; j < splitedData[i].Length; j++)
            {
                excelData[i, j] = splitedData[i][j];
            }
        }
        oSheet.get_Range("A" + bestRow.ToString()).Resize[splitedData.Length, colCount].Value = excelData;
        MainWindow.mainWindowDispacter.BeginInvoke(new System.Action(() => MainWindow.mainWindow.debugTextBox.AppendText("Done with " + rds + " input!" + Environment.NewLine)));
    } 

我最好的猜测是,带有r.Insert的for循环会使它变慢,因为您的numberof很大。这会导致Excel通过一次插入一行来移动整个电子表格的次数

如果一次插入所需数量的行,速度可能会快得多:

 private void shiftRows(int from, int numberof)
 {
      // Excel starts at 1
      from = from+1;
      // Insert numberof rows at row from
      oXL.Rows(String.Format("{0}:{1}", from, from+numberof))
      .Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftDown);
}
可以帮助您的其他问题:

它到底有多快?你想要多快?
在哪种情况下会变慢?

要有效地将值写入工作表,不应直接写入工作表。您需要做的是为行或列声明一个对象数组,或者为网格声明一个二维对象数组。用所需的值填充这些对象。接下来,从目标工作表中声明一个范围对象,然后设置其起始位置偏移量,并根据数组的长度调整其大小。通过使用对象数组设置范围值,写入范围1次

public static void Write(
        _Worksheet worksheet, object[,] values, int rowIndex, int columnIndex, ExcelFormatter formatter)
    {
        if (worksheet == null)
        {
            return;
        }

        if (values == null)
        {
            return;
        }

        var range = (Range)worksheet.Cells.Item[1, 1];

        // range = range.get_Offset(rowIndex, columnIndex);  // this did not work when cell 1,1 is a merged cell (column wise); offset moves by columns first before rows
        range = range.Offset[rowIndex, 0]; // this partially solves the problem 
        range = range.Offset[0, columnIndex];

        // may need a different algo if cell 1,1 is a merged cell (row wise)
        range = range.Resize[values.GetLength(0), values.GetLength(1)];
        range.set_Value(XlRangeValueDataType.xlRangeValueDefault, values);
        if (formatter != null)
        {
            formatter.Invoke(range);
        }

        ReleaseObject(range);
    }

也许值得一试:从Excel中读取所有数据,在应用程序中使用这些数据,然后一次性将其全部写回。我在互操作方面没有太多经验,但性能不佳的主要原因通常是使用了多个范围。如果可能,您应该努力获得一个相对较大的范围,即代表整个工作表的范围,然后对其执行所有必需的操作,然后在其他大范围内重复该操作。@Raidri我得到了工作表的usedRange我会在代码中编辑该范围现在用新的替换工作表usedRange的方法是什么?nvm used oSheet.Cells[oSheet.Rows.Count,oSheet.Columns.Count]=wholeSheet;但仍然很慢……我建议将“Application.EnableAnimations”设置为FALSE