以前在網上看到的都是遍歷那種比較簡單的實體對象,可是若是有實體嵌套,甚至是包含有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的操做類在以前的文章中有,這裏就再也不貼了。