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

时间:2019-04-22 13:33:45

标签: c# epplus

我正在使用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 },它只会返回Units列表中的第一项。

如果我对select new { f.Identifier, f.Name, f.Profile, u }中的每个项目都进行Units,则会创建具有重复的IdentifierNameProfile的新行。

这是我的模特班:

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:B4B5:B6C3:C4C5:C6D3:D4D5:D6. < / p>

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

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

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

2 个答案:

答案 0 :(得分:1)

根据评论,我将避免使用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;
}

答案 1 :(得分:0)

这是一种方法:

给出一个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列表中的所有值。
  • 如果它是第一项,则显示所有属性。如果不是第一项,则仅显示单位。