为ClosedXML循环和行删除优化性能

问题描述 投票:0回答:1

我正在读取Excel文件并循环浏览各行,删除满足条件的行

using (var wb = new XLWorkbook(path))
{
    var ws = wb.Worksheet(sheet);
    int deleted = 0;
    for (int row_i = 2; row_i <= ws.LastRowUsed().RowNumber(); row_i++)
    {
        ExcelRow row = new ExcelRow(ws.Row(row_i-deleted));
        row.styleCol = header.styleCol;
        K key = keyReader(row);
        if (!writeData(row,dict[key])) deleted++;
    }
    wb.Save();
}

对于具有数千行的文件,即使没有删除,或者必须删除数百行,代码也非常慢。

c# optimization closedxml
1个回答
0
投票

您必须执行2个重要的优化。第一列很琐碎,但影响很大:您需要存储最后一列,因为获取该列的函数非常耗时,比您期望的要多。

int lastrow = ws.LastRowUsed().RowNumber();
for (int row_i = 2; row_i <= lastrow; row_i++)

第二个涉及更多,当您不删除单个范围时,它与多个(缓慢的)行/单元格移位(XLShiftDeletedCells.ShiftCellsUp)有关。在这种情况下,我可以建议一种解决方法。在writeData期间不要删除单行-请注意,因此您不会递减

ExcelRow row = new ExcelRow(ws.Row(row_i)); // no deletion in the loop

您的循环索引-但暂时添加一列(temp_col)将行标记为“ ok”或“ skip”并最终对其进行排序,以便您可以删除单个范围内的所有行。

if (deleted > 0)
{
    int lastcol = ws.LastColumnUsed().ColumnNumber();
    var tab = ws.Range(ws.Cell(2, 1), ws.Cell(lastrow, lastcol));
    tab.Sort(temp_col);
    tab = ws.Range(ws.Cell(lastrow - deleted + 1, 1), ws.Cell(lastrow, lastcol));
    tab.Delete(XLShiftDeletedCells.ShiftCellsUp);
}
ws.Column(temp_col).Delete();
© www.soinside.com 2019 - 2024. All rights reserved.