user3756817
user3756817

Reputation: 324

How to use Epplus with cells containing few rows

I want to import some excel file using epplus the problem is that some cells contains more than one row (and that cause a problem

My excel look like this (in realite their is more tests (test2,test3....)

enter image description here

I can only get the first column by this algorithm..but it will be more complicated to get the seconde column

 //this is the list than contain applications (column 2)
ICollection<Application> applications = new  List<Application>();
            int i = 0;

            for (int j = workSheet.Dimension.Start.Row;
                    j <= workSheet.Dimension.End.Row;
                    j=i+1)
            {
                 //this is the object that contain the first column
                //and also a list of the second column  (foreach domain thei `is a list of applications (column 2)`          
                Domaine domaine = new Domaine();

                i += 1;

                //add here and  not last row
                while (workSheet.Cells[i, 1].Text == "" && i < workSheet.Dimension.End.Row)
                {

                    i++;
                }

                if (i > workSheet.Dimension.End.Row)
                    break;
                domaine.NomDomaine = workSheet.Cells[i, 1].Text;
                domaines.Add(domaine);

            }

Edit : in other words is their a way to get the number of rows in one cell , OR a way to duplicate the value of each row in the cell

(for exemple if i have a cell from row 1 to 14 and the row number 5 have value) how can i duplicate that text to all the rows (that will help me solving the problem)

Upvotes: 3

Views: 5887

Answers (1)

Stewart_R
Stewart_R

Reputation: 14485

Those are known as Merged cells. Values from merged cells are stored in the .Value property of the first cell in the merged range. This means we need to do just a little bit more work in order to read the value from a merged cell using EPPlus.

EPPlus provides us with a couple of properties that help us get to the correct reference though. Firstly we can use a cell's .Merge property to find out if it is part of a merged range. Then we can use the the worksheet's .MergedCells property to find the relevant range. It's then just a matter of finding the first cell in that range and returning the value.

So, in summary:

  1. Determine if the cell we need to read from is part of a merged range using .Merge
  2. If so, get the index of the merged range using the worksheet's .MergedCells property
  3. Read the value from the first cell in the merged range

Putting this together we can derive a little helper method to take a worksheet object and row/col indices in order to return the value:

static string GetCellValueFromPossiblyMergedCell(ExcelWorksheet wks, int row, int col)
{
    var cell = wks.Cells[row, col];
    if (cell.Merge)                                              //(1.)
    {
        var mergedId = wks.MergedCells[row, col];                //(2.)
        return wks.Cells[mergedId].First().Value.ToString();     //(3.)
    }
    else
    {
        return cell.Value.ToString();
    }
}

Worked example

If I have a domain class like this:

class ImportedRecord
{
    public string ChildName { get; set; }
    public string SubGroupName { get; set; }
    public string GroupName { get; set; }
}

that I wanted to read from a spreadsheet that looked like this:

excel screenshot

Then I could use this method:

static List<ImportedRecord> ImportRecords()
{
    var ret = new List<ImportedRecord>();
    var fInfo = new FileInfo(@"C:\temp\book1.xlsx");
    using (var excel = new ExcelPackage(fInfo))
    {
        var wks = excel.Workbook.Worksheets["Sheet1"];
        var lastRow = wks.Dimension.End.Row;

        for (int i = 2; i <= lastRow; i++)
        {
            var importedRecord = new ImportedRecord
            {
                ChildName = wks.Cells[i, 4].Value.ToString(),
                SubGroupName = GetCellValueFromPossiblyMergedCell(wks,i,3),
                GroupName = GetCellValueFromPossiblyMergedCell(wks, i, 2)
            };
            ret.Add(importedRecord);
        }
    }

    return ret;
}

static string GetCellValueFromPossiblyMergedCell(ExcelWorksheet wks, int row, int col)
{
    var cell = wks.Cells[row, col];
    if (cell.Merge)
    {
        var mergedId = wks.MergedCells[row, col];
        return wks.Cells[mergedId].First().Value.ToString();
    }
    else
    {
        return cell.Value.ToString();
    }
}

Upvotes: 7

Related Questions