using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; namespace FastExcel { partial class FastExcel { /// /// Dictionary of defined names /// internal IReadOnlyDictionary DefinedNames { get { if (_definedNames == null) { LoadDefinedNames(); } return _definedNames; } } private Dictionary _definedNames; private void LoadDefinedNames() { XDocument document; try { document = XDocument.Load(Archive.GetEntry("xl/workbook.xml").Open()); } catch (Exception exception) { throw new DefinedNameLoadException("Unable to open stream to read internal workbook.xml file", exception); } if (document == null) { throw new DefinedNameLoadException("Unable to load workbook.xml from open stream. Probable corrupt file."); } _definedNames = new Dictionary(); foreach (var e in (from d2 in document.Descendants().Where(dx => dx.Name.LocalName == "definedNames").Descendants() select d2)) { var currentDefinedName = new DefinedName(e); _definedNames.Add(currentDefinedName.Key, currentDefinedName); } } /// /// Retrieves ranges of cells by their defined name /// /// Defined Name /// If scoped to a sheet, the worksheetIndex /// List of cells encapsulated in another list representing seperate ranges public IEnumerable> GetCellRangesByDefinedName(string definedName, int? worksheetIndex = null) { var result = new List>(); string key = !worksheetIndex.HasValue ? definedName : definedName + ":" + worksheetIndex; if (!DefinedNames.ContainsKey(key)) { return result; } string[] references = DefinedNames[key].Reference.Split(','); foreach (string reference in references) { CellRange cellRange; try { cellRange = new CellRange(reference); } catch (ArgumentException) { // reference is invalid or not supported continue; } Worksheet worksheet = Read(cellRange.SheetName); result.Add(worksheet.GetCellsInRange(cellRange).ToList()); } return result; } /// /// Gets all cells by defined name /// Like GetCellRangesByCellName, but just retreives all cells in a single list /// /// /// /// public IEnumerable GetCellsByDefinedName(string definedName, int? worksheetIndex = null) { var cells = new List(); var cellRanges = GetCellRangesByDefinedName(definedName) as List>; foreach (var cellRange in cellRanges) { cells.InsertRange(cells.Count, cellRange); } return cells; } /// /// Returns cell by defined name /// If theres more than one, this is the first one. /// public Cell GetCellByDefinedName(string definedName, int? worksheetIndex = null) { return GetCellsByDefinedName(definedName, worksheetIndex).FirstOrDefault(); } /// /// Returns all cells in a column by name, within optional row range /// /// /// /// /// public IEnumerable GetCellsByColumnName(string columnName, int rowStart = 1, int? rowEnd = null) { var columnCells = GetCellsByDefinedName(columnName) as List; if (!rowEnd.HasValue) { rowEnd = columnCells.Last().RowNumber; } return columnCells.Where(cell => cell.RowNumber >= rowStart && cell.RowNumber <= rowEnd).ToList(); } } }