Search code examples
.netepplus

Why does Dimension.End.Column return an index larger than the last column with any values?


Reading spreadsheets with EPPlus, I was surprised to see Dimension.End.Column returning a higher (1-based) index than the column I know to be the last.

For example, in a spreadsheet like this:

   A       B       C       D...
1  value

I would expect Dimension.End.Column to be 1, corresponding to the first column.

However, it's often larger. Why is that?


Solution

  • To answer this question it is needed to drill deep down into the source code of EpPlus.

    Anyway, here is an extension method that I use to get an actual (valued) dimension and it works just fine even for edge cases:

    public static ExcelAddressBase GetValuedDimension(this ExcelWorksheet worksheet)
    {
        var dimension = worksheet.Dimension;
        if (dimension == null) return null;
        var cells = worksheet.Cells[dimension.Address];
        Int32 minRow = 0, minCol = 0, maxRow = 0, maxCol = 0;
        var hasValue = false;
        foreach (var cell in cells.Where(cell => cell.Value != null))
        {
            if (!hasValue)
            {
                minRow = cell.Start.Row;
                minCol = cell.Start.Column;
                maxRow = cell.End.Row;
                maxCol = cell.End.Column;
                hasValue = true;
            }
            else
            {
                if (cell.Start.Column < minCol)
                {
                    minCol = cell.Start.Column;
                }
                if (cell.End.Row > maxRow)
                {
                    maxRow = cell.End.Row;
                }
                if (cell.End.Column > maxCol)
                {
                    maxCol = cell.End.Column;
                }
            }
        }
        return hasValue ? new ExcelAddressBase(minRow, minCol, maxRow, maxCol) : null;
    }