using System; using System.Collections.Generic; using System.Linq; using System.Text; using OfficeOpenXml.FormulaParsing; using OfficeOpenXml.FormulaParsing.ExcelUtilities; using OfficeOpenXml.FormulaParsing.Excel.Functions; using OfficeOpenXml.FormulaParsing.LexicalAnalysis; using OfficeOpenXml.Utils; using OfficeOpenXml.Style.XmlAccess; namespace OfficeOpenXml.FormulaParsing { public class EpplusExcelDataProvider : ExcelDataProvider { public class RangeInfo : IRangeInfo { internal ExcelWorksheet _ws; CellsStoreEnumerator _values = null; int _fromRow, _toRow, _fromCol, _toCol; int _cellCount = 0; ExcelAddressBase _address; ICellInfo _cell; public RangeInfo(ExcelWorksheet ws, int fromRow, int fromCol, int toRow, int toCol) { _ws = ws; _fromRow = fromRow; _fromCol = fromCol; _toRow = toRow; _toCol = toCol; _address = new ExcelAddressBase(_fromRow, _fromCol, _toRow, _toCol); _address._ws = ws.Name; _values = new CellsStoreEnumerator(ws._values, _fromRow, _fromCol, _toRow, _toCol); _cell = new CellInfo(_ws, _values); } public int GetNCells() { return ((_toRow - _fromRow) + 1) * ((_toCol - _fromCol) + 1); } public bool IsEmpty { get { if (_cellCount > 0) { return false; } else if (_values.Next()) { _values.Reset(); return false; } else { return true; } } } public bool IsMulti { get { if (_cellCount == 0) { if (_values.Next() && _values.Next()) { _values.Reset(); return true; } else { _values.Reset(); return false; } } else if (_cellCount > 1) { return true; } return false; } } public ICellInfo Current { get { return _cell; } } public ExcelWorksheet Worksheet { get { return _ws; } } public void Dispose() { //_values = null; //_ws = null; //_cell = null; } object System.Collections.IEnumerator.Current { get { return this; } } public bool MoveNext() { _cellCount++; return _values.MoveNext(); } public void Reset() { _values.Init(); } public bool NextCell() { _cellCount++; return _values.MoveNext(); } public IEnumerator GetEnumerator() { Reset(); return this; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this; } public ExcelAddressBase Address { get { return _address; } } public object GetValue(int row, int col) { return _ws.GetValue(row, col); } public object GetOffset(int rowOffset, int colOffset) { if (_values.Row < _fromRow || _values.Column < _fromCol) { return _ws.GetValue(_fromRow + rowOffset, _fromCol + colOffset); } else { return _ws.GetValue(_values.Row + rowOffset, _values.Column + colOffset); } } } public class CellInfo : ICellInfo { ExcelWorksheet _ws; CellsStoreEnumerator _values; internal CellInfo(ExcelWorksheet ws, CellsStoreEnumerator values) { _ws = ws; _values = values; } public string Address { get { return _values.CellAddress; } } public int Row { get { return _values.Row; } } public int Column { get { return _values.Column; } } public string Formula { get { return _ws.GetFormula(_values.Row, _values.Column); } } public object Value { get { return _values.Value; } } public double ValueDouble { get { return ConvertUtil.GetValueDouble(_values.Value, true); } } public double ValueDoubleLogical { get { return ConvertUtil.GetValueDouble(_values.Value, false); } } public bool IsHiddenRow { get { var row=_ws._values.GetValue(_values.Row, 0) as RowInternal; if(row != null) { return row.Hidden || row.Height==0; } else { return false; } } } public bool IsExcelError { get { return ExcelErrorValue.Values.IsErrorValue(_values.Value); } } public IList Tokens { get { return _ws._formulaTokens.GetValue(_values.Row, _values.Column); } } } public class NameInfo : ExcelDataProvider.INameInfo { public ulong Id { get; set; } public string Worksheet { get; set; } public string Name { get; set; } public string Formula { get; set; } public IList Tokens { get; internal set; } public object Value { get; set; } } private readonly ExcelPackage _package; private ExcelWorksheet _currentWorksheet; private RangeAddressFactory _rangeAddressFactory; private Dictionary _names=new Dictionary(); public EpplusExcelDataProvider(ExcelPackage package) { _package = package; _rangeAddressFactory = new RangeAddressFactory(this); } public override ExcelNamedRangeCollection GetWorksheetNames(string worksheet) { var ws=_package.Workbook.Worksheets[worksheet]; if (ws != null) { return ws.Names; } else { return null; } } public override ExcelNamedRangeCollection GetWorkbookNameValues() { return _package.Workbook.Names; } public override IRangeInfo GetRange(string worksheet, int fromRow, int fromCol, int toRow, int toCol) { SetCurrentWorksheet(worksheet); var wsName = string.IsNullOrEmpty(worksheet) ? _currentWorksheet.Name : worksheet; var ws = _package.Workbook.Worksheets[wsName]; return new RangeInfo(ws, fromRow, fromCol, toRow, toCol); } public override IRangeInfo GetRange(string worksheet, int row, int column, string address) { var addr = new ExcelAddress(worksheet, address); if (addr.Table != null) { addr.SetRCFromTable(_package, new ExcelAddressBase(row, column, row, column)); } //SetCurrentWorksheet(addr.WorkSheet); var wsName = string.IsNullOrEmpty(addr.WorkSheet) ? _currentWorksheet.Name : addr.WorkSheet; var ws = _package.Workbook.Worksheets[wsName]; //return new CellsStoreEnumerator(ws._values, addr._fromRow, addr._fromCol, addr._toRow, addr._toCol); return new RangeInfo(ws, addr._fromRow, addr._fromCol, addr._toRow, addr._toCol); } public override INameInfo GetName(string worksheet, string name) { ExcelNamedRange nameItem; ulong id; ExcelWorksheet ws; if (string.IsNullOrEmpty(worksheet)) { if(_package._workbook.Names.ContainsKey(name)) { nameItem = _package._workbook.Names[name]; } else { return null; } ws = null; } else { ws = _package._workbook.Worksheets[worksheet]; if (ws !=null && ws.Names.ContainsKey(name)) { nameItem = ws.Names[name]; } else if (_package._workbook.Names.ContainsKey(name)) { nameItem = _package._workbook.Names[name]; } else { return null; } } id = ExcelAddressBase.GetCellID(nameItem.LocalSheetId, nameItem.Index, 0); if (_names.ContainsKey(id)) { return _names[id]; } else { var ni = new NameInfo() { Id = id, Name = name, Worksheet = nameItem.Worksheet==null ? nameItem._ws : nameItem.Worksheet.Name, Formula = nameItem.Formula }; if (nameItem._fromRow > 0) { ni.Value = new RangeInfo(nameItem.Worksheet ?? ws, nameItem._fromRow, nameItem._fromCol, nameItem._toRow, nameItem._toCol); } else { ni.Value = nameItem.Value; } _names.Add(id, ni); return ni; } } public override IEnumerable GetRangeValues(string address) { SetCurrentWorksheet(ExcelAddressInfo.Parse(address)); var addr = new ExcelAddress(address); var wsName = string.IsNullOrEmpty(addr.WorkSheet) ? _currentWorksheet.Name : addr.WorkSheet; var ws = _package.Workbook.Worksheets[wsName]; return (new CellsStoreEnumerator(ws._values, addr._fromRow, addr._fromCol, addr._toRow, addr._toCol)); } public object GetValue(int row, int column) { return _currentWorksheet._values.GetValue(row, column); } public bool IsMerged(int row, int column) { //return _currentWorksheet._flags.GetFlagValue(row, column, CellFlags.Merged); return _currentWorksheet.MergedCells[row, column] != null; } public bool IsHidden(int row, int column) { return _currentWorksheet.Column(column).Hidden || _currentWorksheet.Column(column).Width == 0 || _currentWorksheet.Row(row).Hidden || _currentWorksheet.Row(column).Height == 0; } public override object GetCellValue(string sheetName, int row, int col) { SetCurrentWorksheet(sheetName); return _currentWorksheet._values.GetValue(row, col); } public override ExcelCellAddress GetDimensionEnd(string worksheet) { ExcelCellAddress address = null; try { address = _package.Workbook.Worksheets[worksheet].Dimension.End; } catch{} return address; } private void SetCurrentWorksheet(ExcelAddressInfo addressInfo) { if (addressInfo.WorksheetIsSpecified) { _currentWorksheet = _package.Workbook.Worksheets[addressInfo.Worksheet]; } else if (_currentWorksheet == null) { _currentWorksheet = _package.Workbook.Worksheets.First(); } } private void SetCurrentWorksheet(string worksheetName) { if (!string.IsNullOrEmpty(worksheetName)) { _currentWorksheet = _package.Workbook.Worksheets[worksheetName]; } else { _currentWorksheet = _package.Workbook.Worksheets.First(); } } //public override void SetCellValue(string address, object value) //{ // var addressInfo = ExcelAddressInfo.Parse(address); // var ra = _rangeAddressFactory.Create(address); // SetCurrentWorksheet(addressInfo); // //var valueInfo = (ICalcEngineValueInfo)_currentWorksheet; // //valueInfo.SetFormulaValue(ra.FromRow + 1, ra.FromCol + 1, value); // _currentWorksheet.Cells[ra.FromRow + 1, ra.FromCol + 1].Value = value; //} public override void Dispose() { _package.Dispose(); } public override int ExcelMaxColumns { get { return ExcelPackage.MaxColumns; } } public override int ExcelMaxRows { get { return ExcelPackage.MaxRows; } } public override string GetRangeFormula(string worksheetName, int row, int column) { SetCurrentWorksheet(worksheetName); return _currentWorksheet.GetFormula(row, column); } public override object GetRangeValue(string worksheetName, int row, int column) { SetCurrentWorksheet(worksheetName); return _currentWorksheet.GetValue(row, column); } public override string GetFormat(object value, string format) { var styles = _package.Workbook.Styles; ExcelNumberFormatXml.ExcelFormatTranslator ft=null; foreach(var f in styles.NumberFormats) { if(f.Format==format) { ft=f.FormatTranslator; break; } } if(ft==null) { ft=new ExcelNumberFormatXml.ExcelFormatTranslator(format, -1); } return ExcelRangeBase.FormatValue(value, ft,format, ft.NetFormat); } public override List GetRangeFormulaTokens(string worksheetName, int row, int column) { return _package.Workbook.Worksheets[worksheetName]._formulaTokens.GetValue(row, column); } public override bool IsRowHidden(string worksheetName, int row) { var b = _package.Workbook.Worksheets[worksheetName].Row(row).Height == 0 || _package.Workbook.Worksheets[worksheetName].Row(row).Hidden; return b; } public override void Reset() { _names = new Dictionary(); //Reset name cache. } } }