private void RenderCell(FormulaEvaluator evaluator, TemplateCell cell, params Parameter[] pars) { object value; try { value = cell.IsCalculated ? evaluator.Evaluate(cell.GetString(), pars) : cell.CellType == TemplateCellType.Formula ? cell.Formula : cell.Value; } catch (ParseException ex) { _buff.WriteValue(ex.Message, cell.XLCell); _buff.GetCell(_buff.PrevAddress.RowNumber, _buff.PrevAddress.ColumnNumber).Style.Font.FontColor = XLColor.Red; _errors.Add(new TemplateError(ex.Message, cell.XLCell.AsRange())); return; } IXLCell xlCell; if (cell.CellType == TemplateCellType.Formula) { var r1c1 = cell.XLCell.GetFormulaR1C1(value.ToString()); xlCell = _buff.WriteFormulaR1C1(r1c1, cell.XLCell); } else { xlCell = _buff.WriteValue(value, cell.XLCell); } string EvalString(string str) { try { return(evaluator.Evaluate(str, pars).ToString()); } catch (ParseException ex) { _errors.Add(new TemplateError(ex.Message, cell.XLCell.AsRange())); return(ex.Message); } } if (xlCell.HasComment) { var comment = EvalString(xlCell.Comment.Text); xlCell.Comment.ClearText(); xlCell.Comment.AddText(comment); } if (xlCell.HasHyperlink) { if (xlCell.Hyperlink.IsExternal) { xlCell.Hyperlink.ExternalAddress = new Uri(EvalString(xlCell.Hyperlink.ExternalAddress.ToString())); } else { xlCell.Hyperlink.InternalAddress = EvalString(xlCell.Hyperlink.InternalAddress); } } if (xlCell.HasRichText) { var richText = EvalString(xlCell.RichText.Text); xlCell.RichText.ClearText(); xlCell.RichText.AddText(richText); } }
private void HorizontalTable(object[] items, FormulaEvaluator evaluator) { var rangeStart = _buff.NextAddress; var tags = _tags.CopyTo(_rowRange); for (int i = 0; i < items.Length; i++) { var clmnStart = _buff.NextAddress; foreach (var cell in _cells) { if (cell.CellType != TemplateCellType.NewRow) { RenderCell(items, i, evaluator, cell); } else { _buff.NewRow(); } } var newClmnRng = _buff.GetRange(clmnStart, _buff.PrevAddress); foreach (var mrg in _mergedRanges.Where(r => _optionsRow == null || !_optionsRow.Contains(r))) { var newMrg = mrg.Relative(_rowRange, newClmnRng); newMrg.Merge(false); } if (_rowCnt > 1) { _buff.AddConditionalFormats(_condFormats, _rowRange, newClmnRng); } tags.Execute(new ProcessingContext(newClmnRng, items[i])); if (_rowCnt > 1) { _buff.NewColumn(); } } var resultRange = _buff.GetRange(rangeStart, _buff.PrevAddress); var worksheet = _rowRange.Worksheet; var colNumbers = _cells.Where(xc => xc.XLCell != null) .Select(xc => xc.XLCell.Address.ColumnNumber) .Distinct() .ToArray(); var widths = colNumbers .Select(c => worksheet.Column(c).Width) .ToArray(); var firstCol = colNumbers.Min(); foreach (var col in Enumerable.Range(rangeStart.ColumnNumber, _buff.PrevAddress.ColumnNumber)) { worksheet.Column(firstCol + col - 1).Width = widths[(col - 1) % widths.Length]; } if (_rowCnt == 1) { var rows = resultRange.RowCount() - (_optionsRowIsEmpty ? 0 : 1); _buff.AddConditionalFormats(_condFormats, _rowRange, resultRange.Offset(0, 0, rows, resultRange.ColumnCount())); } /*using (var resultRange = _buff.GetRange(rangeStart, _buff.PrevAddress)) * _rangeTags.Execute(new ProcessingContext(resultRange, new DataSource(items)));*/ }
public ProcessingContext(IXLRange range, object value, FormulaEvaluator evaluator) { Range = range; Value = value; Evaluator = evaluator; }
public SummaryProcessingContext(IXLRange range, IXLRangeRow summaryRow, IDataSource value, FormulaEvaluator evaluator) : base(range, value, evaluator) { SummaryRow = summaryRow; }
public RangeInterpreter(string alias) { _alias = alias; _evaluator = new FormulaEvaluator(); _tagsEvaluator = new TagsEvaluator(); }
private void VerticalTable(object[] items, FormulaEvaluator evaluator) { var rangeStart = _buff.NextAddress; for (int i = 0; i < items.Length; i++) { var startAddr = _buff.NextAddress; IXLAddress rowEnd = null; int row = 1; var tags = _tags.CopyTo(_rowRange); var renderedSubranges = new List <string>(); // render row cells for (var iCell = 0; iCell < _cells.Count; iCell++) { var cell = _cells[iCell]; if (cell.Row > _rowCnt) { break; } if (cell.CellType == TemplateCellType.None) { var xlCell = _rowRange.Cell(cell.Row, cell.Column); var ownRng = _subranges.First(r => r._cells.Any(c => c.CellType != TemplateCellType.None && c.XLCell != null && Equals(c.XLCell.Address, xlCell.Address))); if (!renderedSubranges.Contains(ownRng.Name)) { RenderSubrange(ownRng, items[i], evaluator, cell, tags, ref iCell, ref row); renderedSubranges.Add(ownRng.Name); } } else if (cell.CellType == TemplateCellType.NewRow) { row++; rowEnd = _buff.PrevAddress; _buff.NewRow(startAddr); if (row > _rowCnt) { break; } } else { RenderCell(items, i, evaluator, cell); } } var newRowRng = _buff.GetRange(startAddr, rowEnd); foreach (var mrg in _mergedRanges.Where(r => !_optionsRow.Contains(r))) { var newMrg = mrg.Relative(_rowRange, newRowRng); newMrg.Merge(false); } tags.Execute(new ProcessingContext(newRowRng, items[i], evaluator)); } // Render options row if (!_isOptionsRowEmpty) { foreach (var cell in _cells.Where(c => c.Row == _rowCnt + 1).OrderBy(c => c.Column)) { RenderCell(evaluator, cell); } _buff.NewRow(rangeStart); } // Execute range options tags var resultRange = _buff.GetRange(rangeStart, _buff.PrevAddress); if (!_isOptionsRowEmpty) { var optionsRow = resultRange.LastRow().AsRange(); foreach (var mrg in _mergedRanges.Where(r => _optionsRow.Contains(r))) { var newMrg = mrg.Relative(_optionsRow, optionsRow); newMrg.Merge(); } } // arrage rows height var worksheet = _rowRange.Worksheet; var rowNumbers = _cells.Where(xc => xc.XLCell != null && xc.Row <= _rowCnt) .Select(xc => xc.XLCell.Address.RowNumber) .Distinct() .ToArray(); var heights = rowNumbers .Select(c => worksheet.Row(c).Height) .ToArray(); var firstRow = rowNumbers.Min(); foreach (var row in Enumerable.Range(rangeStart.RowNumber, _buff.PrevAddress.RowNumber)) { worksheet.Row(firstRow + row - 1).Height = heights[(row - 1) % heights.Length]; } if (_isSubrange) { _rangeTags.Execute(new ProcessingContext(resultRange, new DataSource(items), evaluator)); // if the range was increased by processing tags (for example, Group), move the buffer to the last cell _buff.SetPrevCellToLastUsed(); } }