blob: ee79762279518a16b1657c927328496d357bfa83 [file] [log] [blame]
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<object> _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);
_values = new CellsStoreEnumerator<object>(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 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<ICellInfo> 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(_fromCol + rowOffset, _fromCol + colOffset);
}
else
{
return _ws.GetValue(_values.Row + rowOffset, _values.Column + colOffset);
}
}
}
public class CellInfo : ICellInfo
{
ExcelWorksheet _ws;
CellsStoreEnumerator<object> _values;
internal CellInfo(ExcelWorksheet ws, CellsStoreEnumerator<object> 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<Token> 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<Token> Tokens { get; internal set; }
public object Value { get; set; }
}
private readonly ExcelPackage _package;
private ExcelWorksheet _currentWorksheet;
private RangeAddressFactory _rangeAddressFactory;
private Dictionary<ulong, INameInfo> _names=new Dictionary<ulong,INameInfo>();
public EpplusExcelDataProvider(ExcelPackage package)
{
_package = package;
_rangeAddressFactory = new RangeAddressFactory(this);
}
public override ExcelNamedRangeCollection GetWorksheetNames()
{
return _package.Workbook.Worksheets.First().Names;
}
public override ExcelNamedRangeCollection GetWorkbookNameValues()
{
return _package.Workbook.Names;
}
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<object>(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 = _package._workbook.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<object> 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<object>(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);
}
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);
}
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<LexicalAnalysis.Token> 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;
}
}
}