Использование Epplus для генерации xlsx с вложенным списком - PullRequest
1 голос
/ 22 апреля 2019

Я использую 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, он создает новые строки с дубликатами Identifier, Name и Profile.

Вот мой класс модели:

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

Как правильно идентифицировать ячейки с одинаковыми значениями для Identifier, Name и Profile и объединить их?

Например, на скриншоте ниже мне нужно объединить B3:B4, B5:B6, C3:C4, C5:C6, D3:D4, D5:D6.

Я знаю, что могу использовать worksheet.Cells["B3:B4"].Merge = true;, но мне нужен способ, чтобы программно идентифицировать начальную и конечную ячейки с одинаковым значением.

EDIT 1: Добавлен скриншот с дублированными значениями. duplicated values.

РЕДАКТИРОВАТЬ 2 - Исходя из комментария Эрни, мне нужен способ программного поиска в таблице для ячеек с одинаковым значением и объединения их.

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

Исходя из комментариев, я бы избегал метода 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;
}
0 голосов
/ 22 апреля 2019

Вот подход:

Учитывая 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.
  • Если это первый элемент, отобразите все свойства.Если это не первый элемент, отобразите только единицу.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...