高效插入行+数据
Efficently insert rows + data
我有一个有数万行的 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)));
}
我最好的猜测是你的 for
循环与 r.Insert
使它变慢,因为你的 numberof
很大。这导致 Excel 通过一次插入一行来移动整个电子表格 numberof
次。
如果您一次插入所需的行数,可能会快很多:
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);
}
可以提供帮助的其他问题:
它到底有多快,你想要多快?
什么情况下会变慢?
要有效地将值写入工作表,您不应直接直接写入工作表。您需要做的是仅为行或列声明一个对象数组,或者为网格声明一个二维对象数组。用您想要的值填充这些对象。接下来,从目标工作表中声明一个 Range 对象,然后设置其起始位置 (Offset) 并使用数组的长度 (/s) 调整其大小。通过使用对象数组设置范围值来写入范围 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。我需要在此 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)));
}
我最好的猜测是你的 for
循环与 r.Insert
使它变慢,因为你的 numberof
很大。这导致 Excel 通过一次插入一行来移动整个电子表格 numberof
次。
如果您一次插入所需的行数,可能会快很多:
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);
}
可以提供帮助的其他问题:
它到底有多快,你想要多快? 什么情况下会变慢?
要有效地将值写入工作表,您不应直接直接写入工作表。您需要做的是仅为行或列声明一个对象数组,或者为网格声明一个二维对象数组。用您想要的值填充这些对象。接下来,从目标工作表中声明一个 Range 对象,然后设置其起始位置 (Offset) 并使用数组的长度 (/s) 调整其大小。通过使用对象数组设置范围值来写入范围 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);
}