之前在网上看到的都是遍历那种比较简单的实体对象,但是如果有实体嵌套,甚至是包含有List<XXInfo>这种属性的时候就没有办法处理了。通过递归遍历的方式可以完成对复杂实体对象的所有属性的遍历,可以取值和赋值。
下面是关键部分的代码,有什么不对的地方路过的大大一定要指点哈。
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);
}
} }
利用反射实现表格式Excel文档的导出:
上次客户提出了要将数据导出到类似上图的固定格式的Excel文档中,当然真实的表格不是上面那样的,而且表格的格式有十多种,最后采用的解决办法就是利用C#的反射。大概的思路是这样的,为每种导出的表格样式都做一个xml的配置文件,然后记录每个需要复制的文本框的坐标,以及这个值在实体类中的名称,针对上面的那种表格格式,xml配置文件是这样的:
<?xml version="1.0" encoding="utf-8"?> <XML
TableName="table1.xml" OtherInfo="">
<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的操作类在之前的文章中有,这里就不再贴了。
c#用反射原理递归遍历复杂实体对象,码迷,mamicode.com