/// <summary> /// Indexer. Returns the value of the cell at the given string column and 1-based integer row values, e.g. sheetReader["C",7] returns the value /// of the cell at C7, or null if the cell is empty. /// </summary> /// <param name="column"></param> /// <param name="row"></param> /// <exception cref="IndexOutOfRangeException"> /// Will throw if the requested index is beyond the used range of the workbook. Avoid this exception by checking the /// WorksheetDimension or Max/MinRow and Max/MinColumnNumber properties. /// </exception> public object this[string column, int row] { get { var cellRef = new CellRef(row, CellRef.ColumnNameToNumber(column)); var cellRefString = cellRef.ToString(); if (_values.ContainsKey(cellRefString)) { return(_values[cellRefString]); } if (cellRef.ColumnNumber > WorksheetDimension.BottomRight.ColumnNumber || cellRef.Row > WorksheetDimension.BottomRight.Row) { throw new IndexOutOfRangeException(); } var value = GetValue(cellRefString); return(value); } }
private object GetValue(string address) { var cellRef = new CellRef(address); while (ReadNextXmlElementAndLogRowNumber()) { if (_xmlReader.IsStartOfElement("c") && !_xmlReader.IsEmptyElement) { GetCellAttributesAndReadValue(); _values[Address] = Value; if (Address == address) { return(Value); } if (CurrentRowNumber == cellRef.Row) { var columnLetter = _digitsRegex.Replace(Address, ""); var currentColumnNumber = CellRef.ColumnNameToNumber(columnLetter); if (currentColumnNumber > cellRef.ColumnNumber) { SetCursorsToCurrentNullValue(address); return(null); } } } if (_xmlReader.IsStartOfElement("row") && CurrentRowNumber > cellRef.Row) { SetCursorsToCurrentNullValue(address); return(null); } } return(null); }
internal static void AddOptionsFromAttributes(ExcelToEnumerableOptionsBuilder <T> builder, Type type) { MapClassLevelAttributes(builder, type); var properties = type.GetProperties().Distinct().ToArray(); foreach (var property in properties) { var propertyAttributes = property.CustomAttributes.ToArray(); foreach (var propertyAttribute in propertyAttributes) { switch (propertyAttribute.AttributeType.Name) { case nameof(MapsToColumnNumberAttribute): var columnNumber = (int)propertyAttribute.ConstructorArguments[0].Value; ExcelPropertyConfiguration.MapsToColumnNumber(columnNumber, property.Name, builder._options); break; case nameof(MapsToColumnLetterAttribute): var columnLetter = (string)propertyAttribute.ConstructorArguments[0].Value; ExcelPropertyConfiguration.MapsToColumnNumber(CellRef.ColumnNameToNumber(columnLetter), property.Name, builder._options); break; case nameof(OptionalColumnAttribute): ExcelPropertyConfiguration.OptionalColumn(true, property.Name, builder._options); break; case nameof(MapFromColumnsAttribute): var columnNames = ((ReadOnlyCollection <CustomAttributeTypedArgument>)propertyAttribute .ConstructorArguments[0].Value).Select(x => x.Value.ToString()); ExcelPropertyConfiguration.MapFromColumns(columnNames, property.Name, builder._options); break; case nameof(MapsToColumnNamedAttribute): var columnName = (string)propertyAttribute.ConstructorArguments[0].Value; ExcelPropertyConfiguration.MapsToColumnNamed(columnName, property.Name, builder._options); break; case nameof(IgnoreColumnAttribute): ExcelPropertyConfiguration.Ignore(property.Name, builder._options); break; case nameof(MapsToRowNumberAttribute): ExcelPropertyConfiguration.MapsToRowNumber(property.Name, builder._options); break; case nameof(ShouldBeLessThanAttribute): var maxValue = (double)propertyAttribute.ConstructorArguments[0].Value; ExcelPropertyConfiguration.ShouldBeLessThan(maxValue, property.Name, builder._options); break; case nameof(ShouldBeGreaterThanAttribute): var minValue = (double)propertyAttribute.ConstructorArguments[0].Value; ExcelPropertyConfiguration.ShouldBeGreaterThan(minValue, property.Name, builder._options); break; case nameof(NotNullAttribute): ExcelPropertyConfiguration.NotNullProperties(property.Name, builder._options); break; case nameof(ShouldBeOneOfAttribute): // CSH 27112020 We're adding a validator directly here, rather than going via the static ExcelPropertyConfiguration because the validator we're using here using // an enumerable of type object rather than type TProperty (since enforcing argument types at compile time is not possible with Attributes) var objectList = ((ReadOnlyCollection <CustomAttributeTypedArgument>)propertyAttribute .ConstructorArguments[0].Value).Select(x => x.Value); builder._options.Validations[property.Name] .Add(ExcelCellValidatorFactory.CreateShouldBeOneOf(objectList)); break; case nameof(UniqueAttribute): ExcelPropertyConfiguration.Unique(property.Name, builder._options); break; case nameof(RequiredColumnAttribute): ExcelPropertyConfiguration.RequiredColumn(true, property.Name, builder._options); break; } } } }
/// <summary> /// Gets a list of all the cell values within the specified column. /// </summary> /// <param name="column">The string representation of the column, e.g. A, C, AAZ, etc. </param> /// <returns>An enumerable of objects representing the values of cells in the column</returns> public IEnumerable <object> Column(string column) { return(Column(CellRef.ColumnNameToNumber(column))); }
public void ColumnNameToNumberWorks() { CellRef.ColumnNameToNumber("A").Should().Be(1); CellRef.ColumnNameToNumber("Z").Should().Be(26); CellRef.ColumnNameToNumber("AA").Should().Be(27); }