之前在网上看到的都是遍历那种比较简单的实体对象,但是如果有实体嵌套,甚至是包含有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#用反射原理递归遍历复杂实体对象的更多相关文章

  1. 21_java之File对象和递归遍历

    01IO技术概述 * A:IO技术概述 * a: Output * 把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作 * b: Input * 把持久设备上的数据读取到内存中的这 ...

  2. javascript JS递归遍历对象 使用for(variable in object)或者叫for/in和forEach方式

    1.递归遍历查找特定key值(ie9以下不支持forEach) 原文http://www.cnblogs.com/ae6623/p/5938560.html var obj = { first: &q ...

  3. JavaScript对象---递归遍历对象

    JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象. JavaScript 对象 JavaScript 提供多个内建对象,比如 St ...

  4. 如何使用递归遍历对象获得value值

    一般要用到递归,就要判断对象是否和父类型是否一样 这里演示简单的对象递归,还有数组递归类似. var obj = { a:{w:1,y:2,x:3}, b:{s:4,j:5,x:6}, c:{car: ...

  5. DataTable转换为Model实体对象

    记得在学校的时候,接触得最多的就是SqlHelper,每次在读取的时候不管是DataTable还是DataReader转换为实体对象的时候是最恼火的,因为要写很多代码,而且没有什么意义.后面接触到了反 ...

  6. 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java

    前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...

  7. 【Away3D代码解读】(二):渲染核心流程(简介、实体对象收集)

    我之前解析过Starling的核心渲染流程,相比Away3D而言Starling真的是足够简单,不过幸运的是两者的渲染流程是大体上相似的:Starling的渲染是每帧调用Starling类中的rend ...

  8. IO-File 文件 目录 基本操作 递归 遍历

    创建和删除 //创建文件 File file1 = new File("不存在的文件.txt");//注意,这一步并没有创建文件,只是把磁盘中的文件封装成了一个对象 System. ...

  9. 项目中常用方法总结(将将DataTable数据集映射到实体对象)【转】

    本篇把项目中用到的一些通用方法总结出来, 这些方法因为经常需要在项目中用到,所以把它们归纳在一起, 形成一个.dll 文件是一个理想的选择. 这样也便于日后缩短开发周期. 一. 把一个DataGrid ...

随机推荐

  1. Servlet & JSP - 转发与重定向的区别

    本文转载自:http://blog.csdn.net/kobejayandy/article/details/13762043 转发 转发的原理,可以通过下图展示: 浏览器的请求发送给组件 1,组件 ...

  2. BootStrap glyphicons字体图标

    本章将讲解Bootstrap glyphicons字体图标,并通过一些实例了解它的使用,字体图标是在 Web 项目中使用的图标字体.字体图标在下载的Bootstrap的fonts文件夹中   本章将讲 ...

  3. sql防注入式

    SQL注入式攻击是利用是指利用设计上的漏洞,在目标服务器上运行Sql命令以及进行其他方式的攻击动态生成Sql命令时没有对用户输入的数据进行验证是Sql注入攻击得逞的主要原因.比如: 如果你的查询语句是 ...

  4. Block深入浅出

    研究工具 clang 为了研究编译器的实现原理,我们需要使用 clang 命令.clang 命令可以将 Objetive-C 的源码改写成 C / C++ 语言的,借此可以研究 block 中各个特性 ...

  5. 使用python发送Email

    import smtplib from email.mime.text import MIMEText def SendEmail(): email = "" #设置收件地址 ma ...

  6. linux同步

    1. 内核同步 主要是防止多核处理器同时访问修改某段代码,或者在对设备驱动程序进行临界区的保护. 1 .互斥量 头文件 #include<linux/mutex.h> 初始化方法: 静态初 ...

  7. [java学习笔记]java语言基础概述之转义字符&break&continue

    1.转义字符 \t:制表符 \n:回车 \b:退格 \r:回车 \":双引号 \\:反斜线(常用于文件路径的书写中)   windows系统中回车符其实是由两个符号组成的,\r\n linu ...

  8. Mysql单实例脚本自动化安装

    安装包:mysql-5.6.31.tar.gz 已有配置文件:my.cnf *注意:本次Mysql的配置文件是在my.cnf的基础上更改得到的,my.cnf存放路径为/opt/rh/my.cnf 脚本 ...

  9. Qt5.4生成安装包过程

    所需工具: 1.  HM NIS Edit 2.  windeployqt.exe 第一个工具需要自己去网上下载,第二个工具可以在qt安装目录下找到:D:\qtopengl\5.4\mingw491_ ...

  10. JS如何获取iframe内html的body值

    default页面: <html> <head> <script type="text/javascript"> window.onload=f ...