首页 > 解决方案 > 如何使用 EPPlus 从 excel 中删除空白列

问题描述

我想删除最后一列或任何在列之间没有标题的空白列不需要的列,然后使用 EPPlus 从每一行和每一列的 Excel 工作表中删除格式。

请查找示例进度。

public static class EpPlusExtension
{
    public static string[] GetHeaderColumns(this ExcelWorksheet sheet)
    {
        List<string> columnNames = new List<string>();
        foreach (var firstRowCell in sheet.Cells[sheet.Dimension.Start.Row, sheet.Dimension.Start.Column, 1, sheet.Dimension.End.Column])
            columnNames.Add(firstRowCell.Text);
        return columnNames.ToArray();
    }

    public static ExcelWorksheet RemoveCellFormatter(this ExcelWorksheet worksheet)
    {
        try
        {
            dynamic cellValue = null;
            int lastColumnWithHeaderIndex = worksheet.GetHeaderColumns().Count();
                for (int i = worksheet.Dimension.Start.Row; i <= worksheet.Dimension.End.Row; i++)
                {
                    for (int j = worksheet.Dimension.Start.Column; j <= lastColumnWithHeaderIndex; j++)
                    {
                        if (worksheet.Cells[i, j].Value != null)
                        {
                            cellValue = worksheet.Cells[i, j].Value;
                            worksheet.Cells[i, j].Clear();
                            worksheet.Cells[i, j].Value = cellValue;
                            cellValue = null;
                        }
                    }
                }
            return worksheet;
        }
        catch (Exception ex)
        {
            _logger.LogError($"Error Message: Exception While clearing formatting from worksheet. |Exception: {ex.Message}");
            return worksheet;
        }
    }
}

示例代码处理最后不需要的列: 在此处输入图像描述

如何处理中间的空列? 在此处输入图像描述

提前致谢

标签: c#epplus

解决方案


我不是 EPPlus 专家,无法找到可以删除“空”列的方法。null但是,正如 VDWWD 所指出的,循环遍历一列的行并检查该列中的所有单元格是否是,如果是,则删除该列应该不难。

显然,如果有很多行,那么这可能不是最好的方法。如果有很多行和列,可能还有另一种选择,但是,在这种情况下,我会假设执行时间是可以接受的。在我的测试中,工作表包含 735 行和 9 列以及两 (2) 个空列,并且花费了不到一秒的时间。

鉴于此,一个简单的解决方案是遍历列。在每次列迭代中,循环遍历所有行。我们将使用两个变量: abool valueFound并将其设置为false。这将用于指示我们是否在单元格中找到了非空值。aList<int> emptyColIndexes是一个列表,ints用于保存工作表中“空”列的索引。

注意:很明显,我们不想在找到空列后立即“删除”。我们只想存储它的索引并稍后删除列。原因……是……在“循环”列时删除列显然会导致问题。因此,我们只想获取“空”列的索引列表。

当循环遍历一列的行时,如果我们找到一个不是的值null,那么我们使用命令设置valueFoundtrue退出行循环break。如果我们遍历一列中的所有行并退出循环,我们将检查valueFound变量,如果它是false,那么这意味着该列中的所有行值都是null,然后我们将该列索引添加到emptyColIndexes列表中。

最后,在收集所有“空”列索引后,我们循环遍历索引并删除列。

注意:此循环需要从“最后一个”列索引开始并移动到第一个。这应该很明显,如果我们删除列表中另一列左侧的一列,那么索引将变得混乱。基本上,我们要从右到左删除列。因此,循环从最后一个索引开始并转到第一个索引。

此外,这并不重要,但是,似乎RemoveCellFormatter没有必要返回工作表。

下面是演示上述内容的代码。

public static void RemoveEmptyColumns(ExcelWorksheet worksheet) {
  try {
    List<int> emptyColIndexes = new List<int>();
    bool valueFound;
    for (int curCol = worksheet.Dimension.Start.Column; curCol <= worksheet.Dimension.End.Column; curCol++) {
      valueFound = false;
      for (int curRow = worksheet.Dimension.Start.Row; curRow <= worksheet.Dimension.End.Row; curRow++) {
        if (worksheet.Cells[curRow, curCol].Value != null) {
          valueFound = true;
          break;
        }
      }
      if (!valueFound) {
        emptyColIndexes.Add(curCol);
      }
    }
    if (emptyColIndexes.Count > 0) {
      for (int i = emptyColIndexes.Count - 1; i >= 0; i--) {
        worksheet.DeleteColumn(emptyColIndexes[i]);
      }
    }
  }
  catch (Exception ex) {
    MessageBox.Show("Error Message: Exception while removing empty columns from worksheet. " + ex.Message);
  }
}

推荐阅读