使用 Epplus 生成带有嵌套列表的 xlsx

Using Epplus to generate xlsx with nested list

我正在使用 EPPlus 生成 xlsx 文档。

我下面的模型包括一个 List<string>,这就是让我感到复杂的地方:

                var tableBody = worksheet.Cells["B2:B2"].LoadFromCollection(
                    from f in saaOperators.OrderBy(x => x.Identifier).Where(t => t.Identifier.StartsWith(worksheet.Name) ||

                    (t.Identifier.StartsWith("W") && worksheet.Name.Equals("BIR")))

                    from u in f.Units

                    select new { f.Identifier, f.Name, f.Profile, u }, true);

如果我正在做 select new {f.Identifier, f.Name, f.Profile, f.Units } 它 returns 只是 Units 列表中的第一项。

如果我对 Units 中的每个项目执行 select new { f.Identifier, f.Name, f.Profile, u },它会创建具有重复 IdentifierNameProfile.[=31 的新行=]

这是我的模型class:

public class SaaOperator
{
    public string Identifier { get; set; }
    public string Name { get; set; }
    public string Profile { get; set; }
    public List<string> Units { get; set; } = new List<string>();
}

识别 IdentifierNameProfile 具有相同值的单元格并合并它们的正确方法是什么?

例如下面的截图我需要合并B3:B4, B5:B6, C3:C4, C5:C6, D3:D4, D5:D6.

我知道我可以使用 worksheet.Cells["B3:B4"].Merge = true;,但我需要一种方法来以编程方式识别具有相同值的开始和结束单元格。

编辑 1: 添加了具有重复值的屏幕截图。

编辑 2 - 根据 Ernie 的评论,我需要一种方法来以编程方式在工作表中搜索具有相同值的单元格并合并它们。

这是一个方法:

给定一个 List<SaaOperator> 或其他 IEnumerable<SaaOperator>:

foreach (var saaOperator in saaOperators)
{
    string[] valuesToDisplay;
    for (var x = 0; x < saaOperator.Units.Count; x++)
    {
        if (x == 0) // show all the properties
            valuesToDisplay = new[]
                {saaOperator.Identifier, 
                 saaOperator.Name, 
                 saaOperator.Profile, 
                 saaOperator.Units[x]};
        else // after the first unit, don't repeat the other properties
            valuesToDisplay = new[]
                {"", "", "", saaOperator.Units[x]};
    }
}

换句话说,

  • 迭代列表中的所有项目
  • 对于每个项目,遍历 Units 列表中的所有值。
  • 如果是第一项,则显示所有属性。如果不是第一项,只显示单位

根据评论,我会避免使用 LoadFromCollection 方法并使用传统的 for,因为您所做的太具体了。而且我也会避免尝试合并单元格,因为这会使事情不必要地复杂化。应该这样做:

var data = saaOperators
    .Where(t => t.Identifier.StartsWith(worksheet.Name) || (t.Identifier.StartsWith("W") && worksheet.Name.Equals("BIR")))
    .OrderBy(x => x.Identifier)
    .ToList();

var r = 2;

worksheet.Cells[r, 1].Value = "Identifier";
worksheet.Cells[r, 2].Value = "Name";
worksheet.Cells[r, 3].Value = "Profile";
worksheet.Cells[r, 4].Value = "Unit";
r++;

for (var i = 0; i < data.Count; i++)
{
    var op = data[i];
    worksheet.Cells[r + i, 1].Value = op.Identifier;
    worksheet.Cells[r + i, 2].Value = op.Name;
    worksheet.Cells[r + i, 3].Value = op.Profile;

    if (!op.Units.Any())
        continue;

    for (var j = 0; j < op.Units.Count; j++)
        worksheet.Cells[r + i + j, 4].Value = op.Units[j];

    r += op.Units.Count - 1;
}