使用ClosedXML删除多个单元格

时间:2017-02-14 21:56:37

标签: c# excel closedxml

我必须从Excel表格中删除空单元格。我们使用创建和编辑文件ClosedXML。

示例Excel-Before:

    XX  XX                  XX              XX  XX
    XX  XX                  XX              XX  XX
XX  XX  XX                  XX              XX  XX
XX  XX  XX                  XX              XX  XX

示例Excel-After:

XX  XX  XX  XX  XX
XX  XX  XX  XX  XX
XX  XX  XX  XX  XX  XX
XX  XX  XX  XX  XX  XX

我的第一次测试是对所有空细胞的预测。但这不起作用,因为只会删除Row中的第一个单元格。

    private void DeleteCell()
    {
        List<IXLCell> AllEmptyCells = ws.Cells().Where(w => String.IsNullOrEmpty(w.Value.ToString())).ToList();

        foreach(IXLCell cell in AllEmptyCells)
        {
            cell.Delete(XLShiftDeletedCells.ShiftCellsLeft);
        }
    }

我的第二次测试正在进行,但需要很长时间才能完成。每次调用时,列表都将是新生成的,直到列表为空。

    private void DeleteCell()
    {
        List<IXLCell> AllEmptyCells = ws.Cells().Where(w => String.IsNullOrEmpty(w.Value.ToString())).ToList();
        if(AllEmptyCells.Count > 0)
        {
            ws.Cell(AllEmptyCells.FirstOrDefault().Address).Delete(XLShiftDeletedCells.ShiftCellsLeft);
            DeleteCell();
        }

    }

对于100行,这部分将运行~2分钟。有谁知道更好的方法?

3 个答案:

答案 0 :(得分:0)

您可以查看ws.Cells(),而不是遍历ws.RangeUsed().Cells()中的所有单元格。这将忽略实际使用的最后一个单元格之后的所有单元格。

答案 1 :(得分:0)

  1. 您枚举工作表中的所有单元格,而不仅仅是已使用的区域。
  2. 通过删除单元格,您可以将新(空)单元格移动到您的范围内,并将包含内容的单元格移动到空单元格的位置。
  3. 更快更清洁的方法是这样的:

    int maxColNo = sheet.LastColumnUsed().ColumnNumber();
    foreach (var row in sheet.RowsUsed())
    {
        for (int colNo = maxColNo; colNo > 0; colNo--)
        {
            if (row.Cell(colNo).IsEmpty())
            {
                row.Cell(colNo).Delete(XLShiftDeletedCells.ShiftCellsLeft);
            }
        }
    }
    

答案 2 :(得分:0)

我现在在列表中使用Reverse<T>进行枚举。我比之前快一点。我不需要递归调用我的方法。

    private void DeleteCell()
    {
        AllEmptyCells = ws.Cells().Where(w => String.IsNullOrEmpty(w.Value.ToString())).ToList();

        foreach(var item in AllEmptyCells.Reverse<IXLCell>())
        {
            ws.Cell(item.Address.RowNumber, item.Address.ColumnNumber).Delete(XLShiftDeletedCells.ShiftCellsLeft);
        }
    }