Esempio n. 1
0
        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();
            }
        }