使用EPPlus获取合并单元格区域

10
我正在使用EPPlus读取Excel文件。

我有一个单元格是合并单元格的一部分。如何获取包含此单元格的合并范围?

例如:

假设范围("A1:C1")已合并。

给定范围“B1”,它的Merge属性将为true,但没有办法根据单个单元格获取合并范围。

如何获取合并范围?

我希望有一个“.MergedRange”可以返回Range ("A1:C1")。

4个回答

13

开箱即用的属性中没有这样的属性,但是工作表有一个MergedCells属性,其中包含工作表中所有合并单元格地址的数组以及一个GetMergeCellId()方法,该方法将为给定单元格地址提供索引。

因此,我们可以将它们组合成一个小的扩展方法,您可以使用它来获取地址。类似这样:

public static string GetMergedRangeAddress(this ExcelRange @this)
{
    if (@this.Merge)
    {
        var idx = @this.Worksheet.GetMergeCellId(@this.Start.Row, @this.Start.Column);
        return @this.Worksheet.MergedCells[idx-1]; //the array is 0-indexed but the mergeId is 1-indexed...
    }
    else
    {
        return @this.Address;
    }
}

您可以按以下方式使用:

using (var excel = new ExcelPackage(new FileInfo("inputFile.xlsx")))
{
    var ws = excel.Workbook.Worksheets["sheet1"];
    var b3address = ws.Cells["B3"].GetMergedRangeAddress();

}

(请注意,如果您在多单元格范围上使用此方法,它将仅返回范围中第一个单元格的合并单元格地址)


6
您可以从工作表中获取所有合并单元格,因此可以使用以下方法找到特定单元格所属的合并范围:
 public string GetMergedRange(ExcelWorksheet worksheet, string cellAddress)
    {
        ExcelWorksheet.MergeCellsCollection mergedCells = worksheet.MergedCells;
        foreach (var merged in mergedCells)
        {
            ExcelRange range = worksheet.Cells[merged];
            ExcelCellAddress cell = new ExcelCellAddress(cellAddress);
            if (range.Start.Row<=cell.Row && range.Start.Column <= cell.Column)
            {
                if (range.End.Row >= cell.Row && range.End.Column >= cell.Column)
                {
                    return merged.ToString();
                }
            }
        }
        return "";
    }

更新:

事实证明使用EPPLUS有更简单的方法,只需按照以下步骤操作:

var mergedadress = worksheet.MergedCells[row, column];

例如,如果B1在合并单元格"A1:C1"中:
 var mergedadress = worksheet.MergedCells[1, 2]; //value of mergedadress will be "A1:C1".

2是列号,因为B是第二列。


很抱歉,这个不起作用。merged只是一个字符串,所以.Contains(cellAddress)检查"B1"是否是"A1:C3"的子字符串(但它不是),因此返回一个空字符串,而我们希望它返回"A1:C3"。 - Stewart_R
请检查更新后的答案,我已经用许多例子测试过它,它是有效的。 - Yahya Hussein
抱歉,我不明白MergedCells中的[1,2]是什么意思。我已经合并了G、H、I三列,但我想要的值在G列中。我该怎么使用它? - Nikos
[1,2] 分别代表行和列。因此,如果您想要检查合并单元格 H4 属于哪个范围,可以编写 var mergedadress = worksheet.MergedCells[4, 8]; 因为它是第4行,H是第8列。 - Yahya Hussein

1
这将为您提供合并单元格的精确宽度:
workSheet.Cells[workSheet.MergedCells[row, col]].Columns 

1

这不是直接回答Stewart的完美答案,但我来到这里是为了寻找一种获取单元格值的方法,无论它是否是较大合并单元格的一部分,所以我改进了Stewart的代码:

public static string GetVal(this ExcelRange @this)
{
    if (@this.Merge)
    {
        var idx = @this.Worksheet.GetMergeCellId(@this.Start.Row, @this.Start.Column);
        string mergedCellAddress = @this.Worksheet.MergedCells[idx - 1];
        string firstCellAddress = @this.Worksheet.Cells[mergedCellAddress].Start.Address;
        return @this.Worksheet.Cells[firstCellAddress].Value?.ToString()?.Trim() ?? "";
    }
    else
    {
        return @this.Value?.ToString()?.Trim() ?? "";
    }
}

然后像这样调用它

var worksheet = package.Workbook.Worksheets[i];
var rowCount = worksheet.Dimension.Rows;
var columnCount = worksheet.Dimension.Columns;

for (int row = 1; row <= rowCount; row++)
{
    for (int col = 1; col <= columnCount; col++)
    {
        string val = worksheet.Cells[row, col].GetVal();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接