【问题标题】:Delete Multiple Cells with ClosedXML使用 ClosedXML 删除多个单元格
【发布时间】:2017-02-14 21:56:37
【问题描述】:

我必须从 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

我的第一个测试是对所有空单元格进行 foreach。但这不起作用,因为只会删除 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 分钟。有谁知道更好的方法吗?

【问题讨论】:

    标签: c# excel closedxml


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:
      1. 您可以枚举工作表中的所有单元格,而不仅仅是使用的区域。
      2. 通过删除单元格,您可以将新(空)单元格移动到您的范围内,并将包含内容的单元格移动到空单元格的位置。

      一种更快、更简洁的方法是这样的:

      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);
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        我现在在我的列表中使用Reverse&lt;T&gt; 进行枚举。我比以前快一点。我不需要递归调用我的方法。

            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);
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多