public class RdlcHelper
    {
        /// <summary>
        /// 对应XML 的文件地址,每个RdlcHelper实体操作 只对应一个文件,不管是本地的还是服务器上的
        /// </summary>
        public string RdlcFile { get; private set; }


        public RdlcHelper()
        {
        }

        #region 从rdlc文件里面读取字段和字段类型
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName">RDLC文件地址</param>
        //public RdlcHelper(string fileName)
        //{
        //    RdlcFile = fileName;

        ////创建xml对象
        //XmlDocument xdoc = new XmlDocument();
        ////加载xml地址
        //xdoc.Load(fileName);
        ////获取根节点
        //XmlNode xReport = xdoc.DocumentElement;
        ////获取根节点的名称空间
        //string xmlns = xReport.Attributes["xmlns"].Value;
        ////获取或设置用于在 XML 绑定中执行可以识别命名空间的 XPath 查询
        //XmlNamespaceManager xnm = new XmlNamespaceManager(xdoc.NameTable);
        ////加载命名空间
        //xnm.AddNamespace("tk", xmlns);
        ////查找指定的节点
        //XmlNode node = xdoc.SelectSingleNode("/tk:Report/tk:DataSets/tk:DataSet/tk:Fields", xnm);
        //if (node == null)
        //    return;


        //FieldList = new Fields();
        ////遍历节点属性值
        //foreach (System.Xml.XmlNode xn in node.ChildNodes)
        //{
        //    FieldList.Add(new Field(xn));
        //}
        //} 
        #endregion


        /// <summary>
        /// 搜索xml方法
        /// </summary>
        /// <param name="list">搜索条件的集合</param>
        /// <param name="xmlKey">xml键</param>
        /// <returns>本地xml地址</returns>
        public bool SearchXmlFile(Filters list, string SaveUrl, string rdlcPath, out string ErrMsg)
        {
            try
            {
                ErrMsg = string.Empty;
                XmlDocument xd = SearchXmlFile(list, rdlcPath, out ErrMsg);

                if (string.IsNullOrEmpty(ErrMsg))
                {
                    xd.Save(SaveUrl);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                ErrMsg = ex.Message;
                return false;
            }
        }

        public XmlDocument SearchXmlFile(Filters list, string rdlcPath, out string ErrMsg)
        {
            ErrMsg = string.Empty;
            try
            {
                //创建xml对象
                XmlDocument xd = new XmlDocument();
                //加载xml地址
                xd.Load(rdlcPath);
                //获取根节点
                XmlNode xReport = xd.DocumentElement;
                //获取根节点的名称空间
                string xmlns = xReport.Attributes["xmlns"].Value;

                //获取或设置用于在 XML 绑定中执行可以识别名称空间的 XPath 查询
                XmlNamespaceManager xnm = new XmlNamespaceManager(xd.NameTable);
                //加载xml名称空间
                xnm.AddNamespace("tk", xmlns);
                xnm.AddNamespace("rp", xmlns);
                //获取字段的节点,有两中类型节点
                XmlNode node = xd.SelectSingleNode("/tk:Report/tk:Body/rp:ReportItems/rp:Table", xnm);
                if (node == null)
                    node = xd.SelectSingleNode("/tk:Report/tk:Body/tk:ReportItems/rp:Matrix", xnm);
                if (node == null)
                    return xd;

                XmlElement Filters = GetFilters(list, xd, xmlns);

                //搜索条件节点不为空
                if (Filters != null)
                {
                    node.AppendChild(Filters);
                }
                return xd;
            }
            catch (Exception ex)
            {
                ErrMsg = ex.Message;
                return null;
            }
        }

        private XmlElement GetFilters(Filters list, XmlDocument xd, string xmlns)
        {
            //创建一个xml元素对象(搜索条件节点)
            XmlElement filters = null;

            //创建(搜索条件节点)
            if (list.Count > 0)
            {
                filters = xd.CreateElement("Filters");
                filters.SetAttribute("xmlns", xmlns);
            }

            //用来做判断条件
            AndOrEnums andOr = AndOrEnums.None;
            foreach (Filter fi in list)
            {
                //创建搜索条件xml节点
                XmlElement Filter = xd.CreateElement("Filter");
                XmlElement FilterExpression = xd.CreateElement("FilterExpression");
                //判断是否连续都是Equal条件,是就往节点里面追加参数值并把搜索条件改成In
                if (andOr == AndOrEnums.Or)
                {
                    //获取最后一个Filter节点
                    XmlNode lastChild = filters.LastChild;
                    //获取条件节点
                    XmlNode nodeFilter = lastChild.SelectSingleNode("Operator");
                    nodeFilter.InnerText = "In";
                    //获取值的节点
                    XmlNode nodeFilterValues = lastChild.SelectSingleNode("FilterValues");
                    //值子节点添加到值的节点
                    nodeFilterValues.AppendChild(FilterType(fi, xd));
                }
                else
                {
                    //字段
                    if (fi.Field.TypeCode == TypeCode.String)
                        FilterExpression.InnerText =string.Format( "=TRIM(Fields!{0}.Value)", fi.Field.Name);
                    else if (fi.Field.TypeCode == TypeCode.DateTime)
                        FilterExpression.InnerText =string.Format( "=CDate(Fields!{0}.Value).Date()",fi.Field.Name);
                    else
                        FilterExpression.InnerText =string.Format( "=Fields!{0}.Value", fi.Field.Name );
                    Filter.AppendChild(FilterExpression);

                    //条件
                    XmlElement Operator = xd.CreateElement("Operator");
                    if (fi.OperatorType == OperatorEnums.Like && fi.Field.TypeCode != TypeCode.String)
                        Operator.InnerText = OperatorEnums.Equal.ToString();
                    else
                        Operator.InnerText = fi.OperatorType.ToString();
                    Filter.AppendChild(Operator);
                    //参数
                    XmlElement FilterValues = xd.CreateElement("FilterValues");
                    FilterValues.AppendChild(FilterType(fi, xd));
                    Filter.AppendChild(FilterValues);
                    filters.AppendChild(Filter);
                }
                andOr = fi.AndOr;
            }
            return filters;
        }

        private XmlElement FilterType(Filter fi, XmlDocument xd)
        {
            XmlElement FilterValue = xd.CreateElement("FilterValue");
            TypeCode type = fi.Field.TypeCode;//.FiltersType;
            string value = fi.Value;//.Values;
            //判断字段类型  

            if (type == TypeCode.Decimal)
                FilterValue.InnerText = string.Format("=CDEC({0})", value);
            else if (type == TypeCode.Int32)
                FilterValue.InnerText = string.Format("=INT({0})", value);
            else if (type == TypeCode.Boolean)
                FilterValue.InnerText = string.Format("=CBool({0})", value);
            else if (type == TypeCode.Byte)
                FilterValue.InnerText = string.Format("=CByte({0})", value);
            else if (type == TypeCode.Char)
                FilterValue.InnerText = string.Format("=CChar({0})", value);
            else if (type == TypeCode.Double)
                FilterValue.InnerText = string.Format("=CDbl({0})", value);
            else if (type == TypeCode.Int64)
                FilterValue.InnerText = string.Format("=CInt({0})", value);
            else if (type == TypeCode.Object)
                FilterValue.InnerText = string.Format("=CObj({0})", value);
            else if (type == TypeCode.Single)
                FilterValue.InnerText = string.Format("=CSng({0})", value);
            else if (type == TypeCode.DateTime)
                FilterValue.InnerText = string.Format("=CDate(\"{0}\").Date()", value);
            else if (fi.OperatorType == OperatorEnums.Like)        // 判断条件是否为like,是在值后面加*
                FilterValue.InnerText = "*" + fi.Value + "*";
            else
                FilterValue.InnerText = fi.Value;
            return FilterValue;
        }
    }

  

public enum OperatorEnums
    {
        Equal,
        Like,
        NotEqual,
        GreaterThan,
        GreaterThanOrEqual,
        LessThan,
        LessThanOrEqual,
        TopN,
        BottomN,
        TopPercent,
        BottomPercent,
        In,
    }
    public enum AndOrEnums
    {
        None ,
        And,
        Or,
    }
    public class Filter
    {
        public Field Field { get; set; }
        public OperatorEnums OperatorType { get; set; }
        public string Value { get; set; }
        public AndOrEnums AndOr { get; set; }


        public Filter() { }

        public Filter(Field field, string strOperatorType, string value, AndOrEnums andOr)
        {
            Field = field;
            OperatorEnums operatorType = (OperatorEnums)Enum.Parse(typeof(OperatorEnums), strOperatorType, true);
            OperatorType = operatorType;
            Value = value;
            AndOr = andOr;

        }
        public Filter(Field field, OperatorEnums operatorType, string value, AndOrEnums andOr)
        {
            Field = field;
            OperatorType = operatorType;
            Value = value;
            AndOr = andOr;
        }
    }

    public class Filters : List<Filter>
    {
        // 用于替代ReportSearch中的SerachAndOr方法,代码未整理,命名--(测试版)
        public new void Add(Filter a)
        {
            Filter last = null;
            if (this.Count > 0)
                last = this[this.Count - 1];

            if (last != null)
            {
                if (last.Field == a.Field && last.OperatorType == a.OperatorType && a.OperatorType == OperatorEnums.Equal)
                {
                    last.AndOr = AndOrEnums.Or;// "or";
                }
                else if (!string.IsNullOrEmpty(a.Field.Name))
                    last.AndOr = AndOrEnums.And;// "and";
                else
                    last.AndOr = AndOrEnums.None;
            }
            base.Add(a);
        }
    }

  

public class Field
    {
        public string Name { get; set; }
        public TypeCode TypeCode { get; set; }
        public Fields FieldList { get; private set; }
        public Field()
        {

        }

        public Field(DataTable dt)
        {
            FieldList = new Fields();
            foreach (DataColumn c in dt.Columns)
            {
                Field f = new Field();
                f.Name = c.ColumnName;
                f.TypeCode = Field.GetTypeCode(c.DataType.FullName);
                FieldList.Add(f);
            }
        }

        #region 
        //public Field(XmlNode xmlNode)
        //{
        //    Name = xmlNode.Attributes["Name"].Value;
        //    if (xmlNode.HasChildNodes)
        //    {
        //        foreach (XmlNode node in xmlNode.ChildNodes)
        //        {
        //            if (node.LocalName.ToUpper() == "TYPENAME")
        //            {
        //                TypeCode = GetTypeCode(node.InnerText);
        //                break;
        //            }
        //        }
        //    }
        //}

        //public Field(string name, string typeCode)
        //{
        //    Name = name;
        //    TypeCode = GetTypeCode(typeCode);
        //} 
        #endregion

        public static TypeCode GetTypeCode(string value)
        {
            switch (value)
            {
                case "System.String":
                    return TypeCode.String;
                case "System.Decimal":
                    return TypeCode.Decimal;
                case "System.Byte[]":
                    return TypeCode.Byte;
                case "System.DateTime":
                    return TypeCode.DateTime;
                case "System.Int32":
                    return TypeCode.Int32;
                case "System.bool":
                    return TypeCode.Boolean;
                case "System.Boolean":
                    return TypeCode.Boolean;
                case "System.Single":
                    return TypeCode.Single;
                case "System.Short":
                    return TypeCode.Int16;
                case "System.Double":
                    return TypeCode.Double;
                case "System.Char":
                    return TypeCode.Char;
                case "System.Object":
                    return TypeCode.Object;
                case "System.Integer":
                    return TypeCode.Int32;
                default:
                    {
                        LogHelper.Warn(string.Format("Not Match Type:{0}", value));
                        return TypeCode.String;
                    }
            }
        }
    }
    public class Fields : List<Field>
    {
        public Field Find(string name)
        {
            return this.Find(delegate(Field f) { return f.Name == name; });
        }
    }

  

posted on 2012-12-20 22:56  Tim_wu  阅读(404)  评论(0)    收藏  举报