Example #1
0
        /// <summary>
        /// 解析配置
        /// </summary>
        public void ResolveConfig()
        {
            // 重置填充单元格的行号
            Fill.ForEach(t =>
            {
                t.RowIndex--;
                t.ColumnIndex = PowerExcelConfigCell.ToIndex(t.Col);
            });

            //设置整体属性
            Prop.StartColumnIndex = PowerExcelConfigCell.ToIndex(Prop.StartCol);
            Prop.DemoRow--;
            Prop.StartRow = Prop.DemoRow + 1;

            //设置循环列的 列索引号
            var i = 0;

            Row.ForEach(field =>
            {
                field.ColumnIndex = Prop.StartColumnIndex + i++;
                field.Col         = field.GetColumnChar();
            });


            //设置列的公式信息 将$Field转换成 D{i}
            Row.Where(t => string.IsNullOrEmpty(t.Formula) == false).ToList().ForEach(field =>
            {
                field.Formula = Regex.Replace(field.Formula, @"\$(?<name>\w+)", (match) =>
                {
                    var name = match.Groups["name"]?.Value;
                    if (string.IsNullOrEmpty(name))
                    {
                        return(match.Value);
                    }

                    //查找源字段 得到公式信息
                    var index = Row.FirstOrDefault(t => t.Field == name);
                    if (index == null)
                    {
                        throw new Exception($"行字段中未找到{name}");
                    }
                    return(index.GetColumnChar() + "{i}");
                });
            });
        }
Example #2
0
        /// <summary>
        /// 应用规则
        /// </summary>
        private void ApplyRule()
        {
            //单独存放一个工作簿存放所有的数据
            var sheetName = $"ref_rule";
            var sheetRef  = _workbook.CreateSheet(sheetName);//名为ref的工作表

            //循环 i 作为数据存储的列
            // 第一组数据 存储在第一列
            // 第二组数据 存储在第二列
            // 以此类推
            for (int i = 0; i < _rules.Count; i++)
            {
                var rule = _rules[i];

                var options = rule.Source;

                if (options.Count == 0)
                {
                    continue;
                }

                //在当前列 保存所有数据, 所有数据是存储在行上
                for (var j = 0; j < options.Count; j++)
                {
                    var row = sheetRef.GetRow(j) ?? sheetRef.CreateRow(j);
                    row.CreateCell(i).SetCellValue(options[j]);
                }

                //在Excel工作簿中增加此数据范围
                IName range = _workbook.CreateName();//创建一个命名公式

                //获取当前列的字符串列信息,如 1=>A , 2=>B
                var colChar = PowerExcelConfigCell.ToColumnChar(i + 1);

                //公式范围格式应为:A1-A50  B1:B25
                range.RefersToFormula = $"{sheetName}!${colChar}$1:${colChar}${options.Count}"; //公式内容,就是上面的区域
                range.NameName        = $"rule_{i}";                                            //公式名称,可以在"公式"-->"名称管理器"中看到

                //规则也保存该名称,留着后面使用
                rule.RuleName = range.NameName;

                //if (rule.RowField != null && _dtList.Rows.Count > 0)
                //应用到行级字段
                if (rule.RowField != null)
                {
                    foreach (var field in rule.RowField)
                    {
                        SetField2Select(range.NameName, field);
                    }
                }
                //应用到填充字段
                if (rule.FillField != null)
                {
                    foreach (var field in rule.FillField)
                    {
                        SetField2Select(range.NameName, field);
                    }
                }
            }

            var index = _workbook.GetSheetIndex(sheetRef);

            _workbook.SetSheetHidden(index, _config.Prop.Debug ? false : true);
        }
Example #3
0
        /// <summary>
        /// 校验单元格是否通过验证
        /// </summary>
        /// <param name="rowIndex">行号</param>
        /// <param name="field">字段列信息</param>
        /// <param name="cellVal"></param>
        private void ValidateCellValue(int rowIndex, PowerExcelConfigCell field, object cellVal)
        {
            var attr        = field.Attribute;
            var isEmptyCell = cellVal == null || string.IsNullOrEmpty(cellVal.ToString());

            //没有配置校验规则 就放弃校验
            if (attr != null)
            {
                //校验不能为空
                if (attr.Required && isEmptyCell == true)
                {
                    _errors.Add(new ErrorDTO($"{field.Title}  ", $"{field.Title}为必填项")
                    {
                        ColName = field.Col, RowIndex = rowIndex + 1
                    });
                    return;
                }
                //校验邮箱
                if (attr.Validate == nameof(ValidateRule.mail) && isEmptyCell == false)
                {
                    Regex _mail = new Regex(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");
                    if (_mail.IsMatch(cellVal.ToString()) == false)
                    {
                        _errors.Add(new ErrorDTO($"{field.Title} ", $"邮箱:{cellVal} 格式不正确")
                        {
                            ColName = field.Col, RowIndex = rowIndex + 1
                        });
                    }
                }
            }
            //空数据就没有必要做其他类型的校验
            if (isEmptyCell)
            {
                return;
            }
            //存在数据在做校验 金额列校验最大值和最小值
            if (field.CellType == "number")
            {
                double val;
                if (cellVal is double)
                {
                    val = (double)cellVal;
                }
                else if (double.TryParse(cellVal.ToString(), out val) == false)
                {
                    _errors.Add(new ErrorDTO($"{field.Title} ", $"无效数值{cellVal}")
                    {
                        ColName = field.Col, RowIndex = rowIndex + 1
                    });
                }
                if (attr != null)
                {
                    if (val < attr.Min)
                    {
                        _errors.Add(new ErrorDTO($"{field.Title} 超过最小值", $"{val} 小于 {attr.Min}")
                        {
                            ColName = field.Col, RowIndex = rowIndex + 1
                        });
                    }
                    else if (val > attr.Max)
                    {
                        _errors.Add(new ErrorDTO($"{field.Title} 超过最大值", $"{val} 大于 {attr.Max}")
                        {
                            ColName = field.Col, RowIndex = rowIndex + 1
                        });
                    }
                }
            }
            else if (field.CellType == "text")
            {
            }
            else if (field.CellType == "date")
            {
                //单元格如果是日期格式,在非空前提下,必须校验时间格式
                if (isEmptyCell == false)
                {
                    DateTime val;
                    if (cellVal is DateTime)
                    {
                        val = (DateTime)cellVal;
                    }
                    else if (DateTime.TryParse(cellVal.ToString(), out val) == false)
                    {
                        _errors.Add(new ErrorDTO($"{field.Title} ", $"时间值,{cellVal} 格式不正确")
                        {
                            ColName = field.Col, RowIndex = rowIndex + 1
                        });
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// 设置单元格的值
        /// </summary>
        /// <param name="cell">单元格</param>
        /// <param name="filed">字段</param>
        /// <param name="dataRowIndex">行号 用于设置公式</param>
        /// <param name="cellVal">单元格值</param>
        private void SetCellValue(ICell cell, PowerExcelConfigCell filed, int dataRowIndex, string cellVal)
        {
            //设置单元格类型
            //如果没有公式,且指定了单元格类型,直接设置类型
            var cellType = filed.GetCellType();

            if (string.IsNullOrEmpty(filed.Formula) && cellType != CellType.Unknown)
            {
                cell.SetCellType(cellType);
            }
            else
            {
                cell.SetCellType(CellType.Formula);
            }
            //数值列,尝试将数据转换为数值
            if (cell.CellType == CellType.Numeric)
            {
                //获取格式信息
                string formatCode = _df.GetFormat(cell.CellStyle.DataFormat);

                //是否是日期列
                if (DateUtil.IsCellDateFormatted(cell))
                {
                    var val = cellVal.AsDateTime();
                    if (val != DateTime.MinValue)
                    {
                        cell.SetCellValue(val);
                    }
                }
                else
                {
                    // 否则就是其他数值列类型
                    double num = cellVal.AsDouble(double.MinValue);
                    if (num == double.MinValue)
                    {
                        //转换失败,直接赋值
                        cell.SetCellValue(cellVal);
                    }
                    else
                    {
                        //检测是否是百分比 是的话,手动除以100,因为程序里通常存的是50,表示50%
                        if (formatCode.EndsWith("%"))
                        {
                            cell.SetCellValue(num / 100);
                        }
                        else
                        {
                            cell.SetCellValue(num);
                        }
                    }
                }
            }
            else if (cell.CellType == CellType.Formula)
            {
                //公式列信息, {i} 标示当前行
                cell.CellFormula = filed.Formula.Replace("{i}", (dataRowIndex + 1).ToString());
            }
            else
            {
                cell.SetCellValue(cellVal);
            }
        }