c#用反射原理遞歸遍歷複雜實體對象

以前在網上看到的都是遍歷那種比較簡單的實體對象,可是若是有實體嵌套,甚至是包含有List<XXInfo>這種屬性的時候就沒有辦法處理了。經過遞歸遍歷的方式能夠完成對複雜實體對象的全部屬性的遍歷,能夠取值和賦值。node

下面是關鍵部分的代碼,有什麼不對的地方路過的大大必定要指點哈。web

using System.Reflection;數據庫

public System.Text.StringBuilder strB = new System.Text.StringBuilder();     public void GetInfoPropertys(object objInfo)     {         if (objInfo == null) return;         Type tInfo = objInfo.GetType();         PropertyInfo[] pInfos = tInfo.GetProperties();         if (tInfo.IsGenericType)         {             System.Collections.ICollection Ilist = objInfo as System.Collections.ICollection;             if (Ilist != null)             {                 strB.AppendFormat("集合子屬性{0}<br/>", Ilist.Count);                 foreach (object obj in Ilist)                 {                     GetInfoPropertys(obj);                 }             }             else             {                 strB.Append("泛型集合爲空<br/>");             }             return;         }         foreach (PropertyInfo pTemp in pInfos)         {             string Pname = pTemp.Name;             string pTypeName = pTemp.PropertyType.Name;             object Pvalue = pTemp.GetValue(objInfo, null);             if (pTemp.PropertyType.IsValueType || pTemp.PropertyType.Name.StartsWith("String"))             {                 string value = (Pvalue == null ? "爲空" : Pvalue.ToString());                 strB.AppendFormat("屬性名:{0},屬性類型:{1},屬性值:{2}<br/>", Pname, pTypeName, value);             }             else             {                 string value = Pvalue == null ? "爲空" : Pvalue.ToString();                 strB.AppendFormat("<br/><b>子類</b>,屬性名:{0},屬性類型:{1},屬性值:{2}<br/>", Pname, pTypeName, value);                 strB.Append("----------------------------------------------<br/>");                 GetInfoPropertys(Pvalue);ui

            }excel

        }     }orm

 

 

 

利用反射實現表格式Excel文檔的導出:xml

上次客戶提出了要將數據導出到相似上圖的固定格式的Excel文檔中,固然真實的表格不是上面那樣的,並且表格的格式有十多種,最後採用的解決辦法就是利用C#的反射。大概的思路是這樣的,爲每種導出的表格樣式都作一個xml的配置文件,而後記錄每一個須要複製的文本框的座標,以及這個值在實體類中的名稱,針對上面的那種表格格式,xml配置文件是這樣的:對象

<?xml version="1.0" encoding="utf-8"?> <XML TableName="table1.xml" OtherInfo="">blog

  <Field Fname="NAME" PropertyName="NAME" Desc="姓名">     <x>4</x>     <y>3</y>   </Field>   <Field Fname="SEX" PropertyName="SEX" Desc="性別">     <x>10</x>     <y>3</y>   </Field>   <Field Fname="BIRTHDAY" PropertyName="BIRTHDAY" Desc="出生年月">     <x>4</x>     <y>4</y>   </Field>   <Field Fname="Zz" PropertyName="Zz" Desc="政治面貌">     <x>10</x>     <y>4</y>   </Field>   <Field Fname="HunYin" PropertyName="HunYin" Desc="婚姻情況">     <x>4</x>     <y>5</y>   </Field>   <Field Fname="Tel" PropertyName="Tel" Desc="聯繫電話">     <x>10</x>     <y>5</y>   </Field>   <Field Fname="WorkHistory" PropertyName="WorkHistory" Desc="工做經歷">     <x>13</x>     <y>1</y>   </Field>遞歸

  <!--Field Fname="SaleGuid"  PropertyName="SaleList.SaleGuid" Desc="銷售記錄編號">     <x></x>     <y></y>   </Field-->   <Field Fname="ProductGuid"  PropertyName="SaleList.ProductGuid" Desc="貨物編號">     <x>1</x>     <y>8</y>   </Field>   <Field Fname="ProductName"  PropertyName="SaleList.ProductName" Desc="產品編號">     <x>3</x>     <y>8</y>   </Field>   <Field Fname="ProductJiage"  PropertyName="SaleList.ProductJiage" Desc="售價">     <x>5</x>     <y>8</y>   </Field>   <Field Fname="SaleDate"  PropertyName="SaleList.SaleDate" Desc="出售日期">     <x>7</x>     <y>8</y>   </Field> </XML>

而後從數據庫中獲取數據存入到實體類中,用反射遍歷實體類的全部屬性,若是xml中得PropertyName節點的值和當前屬性的屬性名相等,那麼就能夠經過xml提供的座標給Excel表格賦值了。這樣作的一個好處是,能夠實現不一樣表格的通用賦值,即便翻頁顯示也能應對(好比上面的銷售記錄每頁只能顯示4條,而程序中是構造的10條銷售記錄,只能經過分頁顯示完),不用爲每種格式都去寫一種實現,即便表格的樣式有所變更也不用改程序,只需更改一下xml就行了。

語言組織和表達的能力不行,仍是直接上碼:

using System; using System.Collections.Generic; using System.Web; using System.Reflection; using System.Xml; /// <summary> ///Excel導出 /// </summary> public class ExcelExport {

    #region 變量     public List<FiledInfo> FInfoList = new List<FiledInfo>();//xml屬性、座標列表     //public System.Text.StringBuilder strB = new System.Text.StringBuilder();     ExcelOperator excel = null;//Excel操做     int sheetIndex = 0;//excel工做薄索引     #endregion     public ExcelExport()     {         getNodeFromXml();     }     /// <summary>     /// 模擬從數據庫獲取數據     /// </summary>     /// <returns></returns>     public employee GetInfo()     {         employee e = new employee();         e.NAME = "路人甲";         e.SEX = true;         e.HunYin = false;         e.Tel = "15986752131";         e.Zz = "團員";         e.WorkHistory = "暫無";         for (int i = 0; i < 10; i++)         {             SaleInfo s = new SaleInfo();             s.ProductGuid = "產品編號" + i;             s.ProductName = "產品名稱" + i;             s.ProductJiage = 10.23M * i;             s.SaleDate = DateTime.Now.AddDays(i);             e.SaleList.Add(s);         }         return e;     }

    //public string GetProperties()     //{     //    employee emp = GetInfo();     //    GetProperty(emp, "");     //    return strB.ToString();     //}     //private void GetProperty(object obj, string parentProName)     //{     //    if (obj == null) return;     //    Type t = obj.GetType();     //    string strParentProName = (string.IsNullOrEmpty(parentProName) ? "" : parentProName.TrimEnd('.') + ".");     //    if (t.IsGenericType)     //    {     //        System.Collections.ICollection ic = obj as System.Collections.ICollection;     //        foreach (object objTemp in ic)     //        {     //            strB.Append("---------------------<br/>");     //            GetProperty(objTemp, strParentProName);     //        }     //    }     //    else     //    {     //        foreach (PropertyInfo pTemp in t.GetProperties())     //        {     //            string name = pTemp.Name;     //            string typeName = pTemp.PropertyType.FullName;     //            object value = pTemp.GetValue(obj, null);     //            if (pTemp.PropertyType.IsValueType || pTemp.PropertyType.Name.StartsWith("String"))     //            {     //                strB.AppendFormat("屬性名:{0},類型名稱:{1},屬性值:{2}<br/>", strParentProName + name, typeName, value);     //            }     //            else     //            {     //                GetProperty(value, name);     //                strB.AppendFormat("屬性名:{0},類型名稱:{1},屬性值:{2}<br/>", name, typeName, value);

    //            }     //        }     //    }     //}     /// <summary>     /// 屬性賦值     /// </summary>     private void SetPropertyValues(object obj, string parentProName, int index)     {         if (obj == null) return;         Type t = obj.GetType();         string strParentProName = (string.IsNullOrEmpty(parentProName) ? "" : parentProName.TrimEnd('.') + ".");         if (t.IsGenericType)         {             System.Collections.IList ic = obj as System.Collections.IList;             int ICIndex = 0;             foreach (object objTemp in ic)             {                 //strB.Append("---------------------<br/>");                 SetPropertyValues(objTemp, strParentProName, ICIndex);                 ICIndex++;             }         }         else         {             foreach (PropertyInfo pTemp in t.GetProperties())             {                 string name = pTemp.Name;                 string typeName = pTemp.PropertyType.FullName;                 object value = pTemp.GetValue(obj, null);                 if (pTemp.PropertyType.IsValueType || pTemp.PropertyType.Name.StartsWith("String"))                 {                     FiledInfo finfoResult = FInfoList.Find(delegate(FiledInfo finfo) { return finfo.PropertyName == strParentProName + name; });                     if (finfoResult != null)                     {                         //strB.AppendFormat("屬性名:{0},屬性值:{1},座標:x={2},y={3}<br/>", strParentProName + name, value,finfoResult.X,finfoResult.Y);                         int x = Convert.ToInt32(finfoResult.X) + index;                         int y = Convert.ToInt32(finfoResult.Y);                         excel.SetCellValue(sheetIndex, x, y, value.ToString());                     }                 }                 else                 {                     SetPropertyValues(value, name, 0);                 }             }         }     }     /// <summary>     ///     /// </summary>     public employee SetPropertyValue()     {         if (excel == null)         {             excel = new ExcelOperator(@"D:\程序開發\我寫的東東\webLX\Excel\model\yuangong.xls");         }         employee emp = GetInfo();         List<employee> list = FormatEmplyeeObj(emp);         for (int i = 0; i < list.Count;i++ )         {             if (i != 0)             {                 excel.CreateNewSheetByCopy("銷售記錄" + i.ToString());             }         }         foreach (employee empTemp in list)         {             sheetIndex++;             SetPropertyValues(empTemp, "", 0);         }         excel.Close(true);         return emp;     }     /// <summary>     /// 設置值     /// </summary>     private void SetValue()     {         employee e = new employee();         Type t = e.GetType();

    }

    private void getNodeFromXml()     {         FInfoList.Clear();         string strXmlPath = @"D:\程序開發\我寫的東東\webLX\Excel\modelXML\table1.xml";         XmlDocument xml = new XmlDocument();         xml.Load(strXmlPath);         XmlNodeList nodelist = xml.GetElementsByTagName("Field");         foreach (XmlNode node in nodelist)         {             FiledInfo finfo = new FiledInfo();             finfo.PropertyName = node.Attributes["PropertyName"].Value;             finfo.X = node.ChildNodes[1].InnerText;             finfo.Y = node.ChildNodes[0].InnerText;             FInfoList.Add(finfo);         }     }     /// <summary>     /// 格式化員工對象,便於翻頁顯示     /// </summary>     public List<employee> FormatEmplyeeObj(employee emp)     {         List<employee> list = new List<employee>();         if (emp != null)         {             if (emp.SaleList.Count > 4)//銷售記錄每頁顯示4行             {                 for (int i = 0; i < Math.Ceiling(Convert.ToDouble(emp.SaleList.Count) / 4); i++)                 {                     employee infoTemp = new employee();                     CloneEntityObject(emp, infoTemp);                     if ((i + 1) * 4 > emp.SaleList.Count)                     {                         infoTemp.SaleList = infoTemp.SaleList.GetRange(i * 4, emp.SaleList.Count-i*4);//銷售記錄每頁顯示四行                     }                     else                     {                         infoTemp.SaleList = infoTemp.SaleList.GetRange(i * 4, 4);//銷售記錄每頁顯示四行                     }                     list.Add(infoTemp);                 }             }         }         return list;     }     /// <summary>     /// 實體對象拷貝     /// </summary>     /// <param name="srcObj"></param>     /// <param name="desObj"></param>     public void CloneEntityObject(object srcObj, object desObj)     {         if (srcObj.Equals(desObj))         {             return;         }         if (srcObj.GetType() != desObj.GetType())         {             return;         }         System.Reflection.PropertyInfo[] info = srcObj.GetType().GetProperties();         foreach (System.Reflection.PropertyInfo property in info)         {             desObj.GetType().GetProperty(property.Name).SetValue(desObj,             srcObj.GetType().GetProperty(property.Name).GetValue(srcObj, null), null);         }     }

}

另外Excel的操做類在以前的文章中有,這裏就再也不貼了。

相關文章
相關標籤/搜索