前言

  导入excel数据, 在每个项目中基本上都会遇到,第三方插件或者基于微软office,用的最多的就是npoi,aspose.cells和c#基于office这三种方式,其中各有各的优缺点,在这也不再累述。导入npoi封装的方法特别好,但是导出好像没有那一个是进行封装操作的,这两天正好有这块需求,所有就写了一个操作类xx,请不要看到xml就说这不是还要写东西吗,此封装是为了减少代码的书写。功能扩展基本上来源于XML。

需求分析

  1.首先我们要做的就是要把excel中的数据导入到数据库,基于项目中的导入封装,我要吧excel转为对象数据集即:list<model>,那么就需要我们的model要和excle的数据对象进行编写。

  2.在操作过程中会有一些特殊字段,比如PK(主键),外键(客户不知道id只能根据名称找到id)

  3.验证与判断:

        验证---是有些字段必须不能为空等

        判断----对象类型

为此我们就大致知道我们的xml到底该怎么来定义了。如下图

图片上已经大致介绍了每个节点表示的什么意思。其中OracleType如果为空excel可以为空。其他节点就不再累述。

功能实现

  接下来实现就很简单了,只要获取excel数据集,让后获得对象数据的值把它和对象属性字段对象组成键值对,然后利用反射进行对象转换即可。

根基路径读取文件

        /// <summary>
        /// 根据文件路径,读取文件
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="strPath">文件地址</param>
        /// <param name="name">对象xml对应节点</param>
        /// <returns></returns>
        public List<T> ReadData<T>(string strPath, string name)
        {
            List<T> list = new List<T>();
            Workbook wb = new Workbook(strPath);
            foreach (Worksheet ws in wb.Worksheets)
            {
                if (ws.Name == "ReadOnly")
                    continue;

                ExcelToModel r = new ExcelToModel();
                var l = r.ReadTable<T>(ws, name);
                list.AddRange(l);

            }
            return list;
        }

  上述代码中支持多页excel上传如果你们像之上传第一页也行  list.AddRange(l) 合并list,你们可以把对象定义成嵌套对象也可以进行相应处理,在这不再累述。

具体实现代码

  /// <summary>
        /// 获取excel数据集合
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="ws">excel数据流</param>
        /// <param name="xmlNodeName">xml对应节点节点</param>
        /// <returns></returns>
        public List<T> ReadTable<T>(Worksheet ws, string xmlNodeName)
        {

            Cells all = ws.Cells;
            DataSet ds = new DataSet();
            ds.ReadXml(System.Web.HttpContext.Current.Request.MapPath("~/ImportFiles/InputRules.xml"));
            DataTable dt = ds.Tables[xmlNodeName];
            // 数据区
            ;

            List<T> list = new List<T>();
            ; i < all.Rows.Count; i++)
            {
                T model = Activator.CreateInstance<T>();
                Dictionary<string, object> dic = new Dictionary<string, object>();
                ; J < ds.Tables[xmlNodeName].Rows.Count; J++)
                {
                    #region 获取excel表格中的值
                    int ExcelColumn = int.Parse(ds.Tables[xmlNodeName].Rows[J]["ExcelColumn"].ToString());
                    string OracleType = ds.Tables[xmlNodeName].Rows[J]["OracleType"].ToString();
                    string OracleColumn = ds.Tables[xmlNodeName].Rows[J]["OracleColumn"].ToString();

                    string ParameterName = ds.Tables[xmlNodeName].Rows[J]["ParameterName"].ToString();
                    string MethodName = ds.Tables[xmlNodeName].Rows[J]["MethodName"].ToString();
                    string strValue = string.Empty;
                    strValue = ExcelColumn > - ? all[i, ExcelColumn].StringValue : "";
                    if (!Verification(ExcelColumn, OracleType, strValue))
                        break;
                    if (!string.IsNullOrEmpty(ParameterName.ToString()))
                    {
                        string ParameterValue = all[i, int.Parse(ParameterName)].StringValue;
                        var factory = CustomParmeter_Factory.Cresate_CustomParmeter_Factory(MethodName, ParameterValue);
                        strValue = factory.GetCustomParmeter();
                        if (string.IsNullOrEmpty(strValue))
                            break;
                        if (OracleType == "Guid")
                            dic.Add(OracleColumn, new Guid(strValue));
                    }
                    else if (OracleType == "PK")
                        dic.Add(OracleColumn, Guid.NewGuid());
                    else if (OracleType == "datetime")
                        dic.Add(OracleColumn, Convert.ToDateTime(strValue));
                    else if (OracleType == "decimal")
                        dic.Add(OracleColumn, Convert.ToDecimal(strValue));
                    else if (OracleType == "int")
                        dic.Add(OracleColumn, Convert.ToInt32(strValue));
                    else if (OracleType == "Guid")
                        dic.Add(OracleColumn, new Guid(strValue));
                    else
                        dic.Add(OracleColumn, strValue);
                    #endregion
                }

                PropertyInfo[] modelPro = model.GetType().GetProperties();
                 && dic.Count() > )
                {
                    ; z < modelPro.Length; z++)
                    {
                        if (dic.ContainsKey(modelPro[z].Name))
                        {
                            modelPro[z].SetValue(model, dic[modelPro[z].Name], null);
                        }

                    }
                    list.Add(model);
                }
            }
            return list;
        }

  上述代码,首先获取xml各个节点:

    其中ExcelColumn根据此节点获取OracleColumn(数据库对象名称)数据,把两字段存入字典   Dictionary<string, object>;

    OracleType根据此字段进行条件判断,与数据类型转换(excel获取过来的都是string)代码如下:

判断

   /// <summary>
        /// 数据验证
        /// </summary>
        /// <param name="ExcelColumn">excek列号</param>
        /// <param name="OracleType">数据类型</param>
        /// <param name="strValue">获取的值</param>
        /// <returns></returns>
        public static bool Verification(int ExcelColumn, string OracleType, string strValue)
        {
            DateTime dtDate;
            )
                return true;
            if (string.IsNullOrEmpty(OracleType) || string.IsNullOrEmpty(strValue))
                return false;
            if (OracleType == "datetime" && !DateTime.TryParse(strValue, out dtDate))
                return false;
            return true;
        }

转换:

 ; J < ds.Tables[xmlNodeName].Rows.Count; J++)
                {
                    #region 获取excel表格中的值
                    int ExcelColumn = int.Parse(ds.Tables[xmlNodeName].Rows[J]["ExcelColumn"].ToString());
                    string OracleType = ds.Tables[xmlNodeName].Rows[J]["OracleType"].ToString();
                    string OracleColumn = ds.Tables[xmlNodeName].Rows[J]["OracleColumn"].ToString();

                    string ParameterName = ds.Tables[xmlNodeName].Rows[J]["ParameterName"].ToString();
                    string MethodName = ds.Tables[xmlNodeName].Rows[J]["MethodName"].ToString();
                    string strValue = string.Empty;
                    strValue = ExcelColumn > - ? all[i, ExcelColumn].StringValue : "";
                    if (!Verification(ExcelColumn, OracleType, strValue))
                        break;
                    if (!string.IsNullOrEmpty(ParameterName.ToString()))
                    {
                        string ParameterValue = all[i, int.Parse(ParameterName)].StringValue;
                        var factory = CustomParmeter_Factory.Cresate_CustomParmeter_Factory(MethodName, ParameterValue);
                        strValue = factory.GetCustomParmeter();
                        if (string.IsNullOrEmpty(strValue))
                            break;
                        if (OracleType == "Guid")
                            dic.Add(OracleColumn, new Guid(strValue));
                    }
                    else if (OracleType == "PK")
                        dic.Add(OracleColumn, Guid.NewGuid());
                    else if (OracleType == "datetime")
                        dic.Add(OracleColumn, Convert.ToDateTime(strValue));
                    else if (OracleType == "decimal")
                        dic.Add(OracleColumn, Convert.ToDecimal(strValue));
                    else if (OracleType == "int")
                        dic.Add(OracleColumn, Convert.ToInt32(strValue));
                    else if (OracleType == "Guid")
                        dic.Add(OracleColumn, new Guid(strValue));
                    else
                        dic.Add(OracleColumn, strValue);
                    #endregion
                }

其中没有把这段代码独立出来,其实你们可以独立出来的。

其中最为关键的为列号为-1的,表示它是主键或者需要根据excel中的值进行特殊获取。我这边是写了一个工厂类,为什么写工厂,考虑的是为了容易扩展,其实为了装13

    public class CustomParmeter_Factory
    {

        public static ICustomParmeter Cresate_CustomParmeter_Factory(string MethodName, string ParameterName)
        {
            ICustomParmeter newService = null;
            switch (MethodName)
            {
                case "SetLine":
                    newService = new SetLine(ParameterName);
                    break;
                case "SetSegment":
                    newService = new SetSegment(ParameterName);
                    break;
                case "SetSite":
                    newService = new SetSite(ParameterName);
                    break;
            }
            return newService;
        }
    }
    public interface ICustomParmeter
    {
        string GetCustomParmeter();
    }

    public class SetSegment : ICustomParmeter
    {

        private string ParameterName;

        public SetSegment(string _ParameterName)
        {
            ParameterName = _ParameterName;
        }
        public string GetCustomParmeter()
        {
            CustomParmeterCommonService c = new CustomParmeterCommonService();
            return c.GetSegmentPatmet(ParameterName).ToString();

        }
    }

    public class SetLine : ICustomParmeter
    {

        private static string ParameterName;

        public SetLine(string _ParameterName)
        {
            ParameterName = _ParameterName;
        }
        public string GetCustomParmeter()
        {
            CustomParmeterCommonService c = new CustomParmeterCommonService();
            return c.GetLineParmet(ParameterName).ToString();
        }
    }

    public class SetSite : ICustomParmeter
    {

        private string ParameterName;
        public SetSite(string _ParameterName)
        {
            ParameterName = _ParameterName;
        }
        public string GetCustomParmeter()
        {
            CustomParmeterCommonService c = new CustomParmeterCommonService();
            return c.GetSitePatmet(ParameterName).ToString();
        }
    }

其中还有一块比较重要的代买需要说明一下就是字典转为对象类型:

字典转为对象类型

 PropertyInfo[] modelPro = model.GetType().GetProperties();
                 && dic.Count() > )
                {
                    ; z < modelPro.Length; z++)
                    {
                        if (dic.ContainsKey(modelPro[z].Name))
                        {
                            modelPro[z].SetValue(model, dic[modelPro[z].Name], null);
                        }

                    }
                    list.Add(model);
                }

其中如果你想导入新的数据库只需在xml写上自己的对象节点即可:

<?xml version="1.0" encoding="utf-8" ?>
<InputRules>
  <BuildUnit ExcelColumn="-1" DisplayText="主键" OracleColumn="BID" OracleType="PK" ParameterName="" MethodName=""/>
  <BuildUnit ExcelColumn="-1" DisplayText="线路ID" OracleColumn="LineID" OracleType="Guid"  ParameterName="0" MethodName="SetLine"/>
  <BuildUnit ExcelColumn="-1" DisplayText="标段ID" OracleColumn="SegmentID" OracleType="Guid"  ParameterName="1" MethodName="SetSegment"/>
  <BuildUnit ExcelColumn="-1" DisplayText="工点ID" OracleColumn="SiteID" OracleType="Guid"  ParameterName="2" MethodName="SetSite"/>
  <BuildUnit ExcelColumn="0" DisplayText="线路" OracleColumn="LineName" OracleType="varchar50"  ParameterName="" MethodName=""/>
  <BuildUnit ExcelColumn="1" DisplayText="标段" OracleColumn="SegmentName" OracleType="varchar"  ParameterName="" MethodName=""/>
  <BuildUnit ExcelColumn="2" DisplayText="工点" OracleColumn="SiteName" OracleType="varchar"  ParameterName="" MethodName=""/>
  <BuildUnit ExcelColumn="3" DisplayText="计取月度" OracleColumn="RememberTime" OracleType="varchar"  ParameterName="" MethodName=""/>
  <BuildUnit ExcelColumn="4" DisplayText="金额(元)" OracleColumn="Money" OracleType="decimal"  ParameterName="" MethodName=""/>
  <BuildUnit ExcelColumn="5" DisplayText="创建人" OracleColumn="CreateUser" OracleType="varchar"  ParameterName="" MethodName=""/>
  <BuildUnit ExcelColumn="6" DisplayText="创建时间" OracleColumn="CreateTime" OracleType="datetime"  ParameterName="" MethodName=""/>

  <ConstructionUnit ExcelColumn="-1" DisplayText="主键" OracleColumn="CUID" OracleType="PK" ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="-1" DisplayText="线路ID" OracleColumn="LineID" OracleType="Guid"  ParameterName="0" MethodName="SetLine"/>
  <ConstructionUnit ExcelColumn="-1" DisplayText="标段ID" OracleColumn="SegmentID" OracleType="Guid"  ParameterName="1" MethodName="SetSegment"/>
  <ConstructionUnit ExcelColumn="0" DisplayText="线路" OracleColumn="LineName" OracleType="varchar50"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="1" DisplayText="标段" OracleColumn="SegmentName" OracleType="varchar"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="2" DisplayText="使用年月" OracleColumn="UseYears" OracleType="varchar"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="3" DisplayText="使用时间" OracleColumn="UseTime" OracleType="datetime"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="4" DisplayText="付款对象" OracleColumn="Paymenter" OracleType="varchar"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="5" DisplayText="金额(元)" OracleColumn="Money" OracleType="decimal"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="6" DisplayText="用途" OracleColumn="Actiion" OracleType="varchar"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="7" DisplayText="创建人" OracleColumn="CreateUser" OracleType="varchar"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="8" DisplayText="备注" OracleColumn="Remork" OracleType="varchar"  ParameterName="" MethodName=""/>
  <ConstructionUnit ExcelColumn="9" DisplayText="创建时间" OracleColumn="CreateTime" OracleType="datetime"  ParameterName="" MethodName=""/>

  <SupervisionUnit ExcelColumn="-1" DisplayText="主键" OracleColumn="ID" OracleType="PK" ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="-1" DisplayText="线路ID" OracleColumn="LineID" OracleType="Guid"  ParameterName="0" MethodName="SetLine"/>
  <SupervisionUnit ExcelColumn="-1" DisplayText="标段ID" OracleColumn="SegmentID" OracleType="Guid"  ParameterName="1" MethodName="SetSegment"/>
  <SupervisionUnit ExcelColumn="-1" DisplayText="工点ID" OracleColumn="SiteID" OracleType="Guid"  ParameterName="2" MethodName="SetSite"/>
  <SupervisionUnit ExcelColumn="0" DisplayText="线路" OracleColumn="LineName" OracleType="varchar50"  ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="1" DisplayText="标段" OracleColumn="SegmentName" OracleType="varchar"  ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="2" DisplayText="工点" OracleColumn="SiteName" OracleType="varchar"  ParameterName="" MethodName=""/>

  <SupervisionUnit ExcelColumn="3" DisplayText="审核时间" OracleColumn="AuditTime" OracleType="datetime"  ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="4" DisplayText="付款对象" OracleColumn="PayMenter" OracleType="varchar"  ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="5" DisplayText="审核金额" OracleColumn="AuditMoney" OracleType="decimal"  ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="6" DisplayText="创建者" OracleColumn="CreateUser" OracleType="varchar"  ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="7" DisplayText="审核意见" OracleColumn="AuditOpinion" OracleType="varchar"  ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="8" DisplayText="监理审核意见" OracleColumn="BossOpinion" OracleType="varchar"  ParameterName="" MethodName=""/>
  <SupervisionUnit ExcelColumn="9" DisplayText="备注" OracleColumn="Remork" OracleType="varchar"  ParameterName="" MethodName=""/>
</InputRules>

记得特殊字段要在工厂类中添加相应的自定义函数哈,至此整个的功能应该就实现了。

注:如果有更好的实现方案大家请一起讨论,如果有不合理的地方还请你提出你的建议。

基于 Aspose.Cells与XML导入excel 数据----操作类封装的更多相关文章

  1. C# WinForm使用Aspose.Cells.dll 导出导入Excel/Doc 完整实例教程

    1.添加引用: Aspose.Cells.dll(我们就叫工具包吧,可以从网上下载.关于它的操作我在“Aspose.Cells操作说明 中文版 下载 Aspose C# 导出Excel 实例”一文中的 ...

  2. POI 导入excel数据自己主动封装成model对象--代码分析

    上完代码后,对代码进行基本的分析: 1.主要使用反射api将数数据注入javabean对象 2.代码中的日志信息级别为debug级别 3.获取ExcelImport对象后须要调用init()方法初始化 ...

  3. Aspose.Cells for .NET 8.5.0 工具类

    基于 Aspose.Cells for .NET 8.5.0 工具类, Aspose.Cells for .NET 8.5.0 这个自己去CSDN下载里面有破解的,没有破解的导出excel的时候会(A ...

  4. 利用Aspose.Cell控件导入Excel非强类型的数据

    导入Excel的操作是非常常见的操作,可以使用Aspose.Cell.APOI.MyXls.OLEDB.Excel VBA等操作Excel文件,从而实现数据的导入,在导入数据的时候,如果是强类型的数据 ...

  5. 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据

    1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...

  6. 导入excel数据

    前提条件:先要安装好EXCEL软件. 程序中经常要用到导入excel数据的功能.其实通过ole操作excel就简单的几行代码,但记性不好,经常要用经常要找, 还是作篇笔记吧. var ExcelApp ...

  7. aspose.cells根据模板导出excel

    又隔十多天没写博客了,最近都在忙项目的事情,公司人事变动也比较大,手头上就又多了一个项目.最近做用aspose.cells根据模板导出excel报价单的功能,顺便把相关的核心记下来,先上模板和导出的效 ...

  8. 结合bootstrap fileinput插件和Bootstrap-table表格插件,实现文件上传、预览、提交的导入Excel数据操作流程

    1.bootstrap-fileinpu的简单介绍 在前面的随笔,我介绍了Bootstrap-table表格插件的具体项目应用过程,本篇随笔介绍另外一个Bootstrap FieInput插件的使用, ...

  9. Asp.Net Core 导入Excel数据到Sqlite数据库并重新导出到Excel

    Asp.Net Core 导入Excel数据到Sqlite数据库并重新导出到Excel 在博文"在Asp.Net Core 使用 Sqlite 数据库"中创建了ASP.NET Co ...

随机推荐

  1. Unity编辑器下重启

    我们项目AssetBundle打包走的是全自动化流程,打包之前要进行各种资源检测,如果检测顺利通过,则进入打包,否则提示错误资源名称及路径,打包中断!有时候即使资源检测通过也会打包崩溃,初步断定是Un ...

  2. J2EE走向成功路-02-Struts2 配置(Maven)

    在上一篇中,介绍了使用jar包搭建Struts2框架,这一篇中来介绍一下在Maven环境下搭建Struts2框架,主要为配置Maven. 1.下载Maven,官网:http://maven.apach ...

  3. Scala类型系统(sudden thought)

    http://docs.scala-lang.org/tour/lower-type-bounds.html中有一段代码 trait Node[+B] { def prepend(elem: B): ...

  4. 传统 HTML 表单数据的“整存整取”

    在日常开发中,涉及表单的处理司空见惯.过往,在取值和赋值的过程中,借助 jQuery 常常只是逐个控件进行操作,可惜这样开发效率并不高.那么能不能批量获取整个表单的值呢,以及批量为表单赋值. 一.取值 ...

  5. python 携带cookie访问网站(python接口测试post)

    最近在使用自己研究性能测试工具的时候想到,使用python向服务器不断发送数据以作为并发测试.大概情况如下: #coding=utf-8 import urllib2 import urllib im ...

  6. spring mvc 多线程并发

    ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. http://www.xuebuyuan.com/1628190.html 我们 ...

  7. Microsoft Offce 使用纪事:oneNote笔记本分区删除

    OneNote 笔记本和分区删除 OneNote 目前无法在客户端和本地删除已有的笔记本和分区,只能通过OneDrive才能够从云端删除: step1 step2 step3 后记 由于需要登录One ...

  8. 彻底区分html的attribute与dom的property

    当初在学html时始终没有弄清楚的关于attribute与property的区别,竟然在看angular文档时弄明白了. angular官方文档的数据绑定一节提到html attribute与dom ...

  9. 带你领会 线性代数 微积分的本质 3blue1brown 动画效果帅出天际

    前段时间在 哔哩哔哩 上偶然发现了 3blue1brown 精美的动画,配上生动的讲解,非常适合帮助建立数学的形象思维 其中两大系列,非常值得反复观看: 线性代数的本质(Essence of line ...

  10. 【转】Linux设备驱动--块设备(一)之概念和框架

    原文地址:Linux设备驱动--块设备(一)之概念和框架 基本概念   块设备(blockdevice) --- 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时 ...