.net 下批量导入excel的数据

来源:互联网 发布:四轮定位电脑数据图解 编辑:程序博客网 时间:2024/05/29 17:00

功能说明:

   数据已成为一个系统必不可少的一部分,但对于大量的数据信息,手动录入必然是用户不想使用的。如果可以把保存在Excel中的数据一次性导入,那么受到用户的青睐;下面我就大概来讲一下我的实现方法。

 为了使提高它的公用性,我采用.xml文件+反射机制的方法来完成。

1、新建一个名为readExcel.xml的文件。

<Root><Item>  <ItemName>唯一名称</ItemName>  <saveMethod>调用的保存方法:命名空间.类名.方法名</saveMethod>  <Fields>    <Field>      <FieldName>属性名称</FieldName>      <FiledRemark>属性的汉语名称,对应Excel中的列名</FiledRemark>      <isImageUrl>是否是图片地址:true,false</isImageUrl>      <InvokeMethod>调用的转换方法:命名空间.类名.方法名</InvokeMethod>    </Field>     <Field>      <FieldName>属性名称</FieldName>      <FiledRemark>属性的汉语名称,对应Excel中的列名</FiledRemark>      <isImageUrl>是否是图片地址:true,false</isImageUrl>          </Field>    <Field>      <FieldName>属性名称</FieldName>      <IsRelated>是否为关联字段</IsRelated>      <RelatedField>关联字段的汉语名称</RelatedField>      <RelatedMethod>关联值的产生方法:命名空间.类名.方法名</RelatedMethod>      <isImageUrl>是否是图片地址:true,false</isImageUrl>    </Field>  </Fields></Item></Root>

如果要实现上传文件,配置方式可以类似图片的配置方式。

2、完成readExcel.xml文件数据结构。

/// <summary>    /// readExcel.xml的结构    /// </summary>    public class readExcelMap    {        /// <summary>        /// 项名称,唯一标识        /// </summary>        public string itemName { get; set; }        /// <summary>        /// 图片的保存地址        /// </summary>        public string ImageSavePath{get;set;}        /// <summary>        /// 数据的保存方法        /// </summary>        public string saveMethod { get; set; }        /// <summary>        /// 属性列表        /// </summary>        public List<readXmlField> fields { get; set; }            }    public class readXmlField    {        /// <summary>        /// 属性名称        /// </summary>        public string filedName { get; set; }        /// <summary>        /// 属性汉语意思        /// </summary>        public string fieldRemark { get; set; }        /// <summary>        /// 是否是图片地址        /// </summary>        public bool isImageUrl { get; set; }        /// <summary>        /// 值的转换方法        /// </summary>        public string InvokeMethod { get; set; }        /// <summary>        /// 值是否来自关联其他字段        /// </summary>        public bool isRelated { get; set; }        /// <summary>        /// 关联的属性,用逗号隔开        /// </summary>        public string relatedField { get; set; }        /// <summary>        /// 值产生的关联方法        /// </summary>        public string relatedMethod { get; set; }    }

3、利用反射来完成数据的读取、验证数据的有效性、保存到数据库并生产导入报告,最终以excel文件的方式把导入报告反馈给用户。

public class readExcel    {        #region [字段]        //日志记录        private static readonly IWebLog logger = WebLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);        #endregion        public static string leadIn<T>(T obj, string excelFilePath,string imagePath,string itemName)        {                        //导入报告信息            StringBuilder sb = new StringBuilder();            sb.Append("<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">");                       //获取配置信息            readExcelMap node = getXmlMap(itemName);            if (node == null)            {                throw new Exception("未配置的节点");            }            //获取数据信息            DataSet ds=getExcelData(excelFilePath);             //封装报告的表头            sb.Append("<tr>");            foreach (DataColumn column in ds.Tables[0].Columns)            {                sb.AppendFormat("<td>{0}</td>",column.ColumnName);            }            sb.AppendFormat("<td>{0}</td>", "失败原因");            sb.Append("</tr>");            //获取当前的类型            Type type = obj.GetType();            string typeName=type.FullName;            //标记读取数据出错,则不保存            bool isError = false;            foreach (DataRow row in ds.Tables[0].Rows)//遍历每一行数据            {                Assembly asm = Assembly.GetAssembly(type);                T obj1 = (T)asm.CreateInstance(typeName,true);                isError = false;                //给需要赋值的属性赋值                foreach (readXmlField rxf in node.fields)                {                    PropertyInfo property = getPropertyInfo(type,rxf.filedName);                    if (property == null)                        throw new Exception(string.Format("属性名称<{0}>配置错误",rxf.filedName));                    //是否为图片地址                    if (rxf.isImageUrl)                    {                        //判断是否有图片                        if (row[rxf.fieldRemark].ToString().Trim().Equals(""))                        {                            property.SetValue(obj1, Convert.ChangeType("", property.PropertyType), null);                            continue;                        }                        //获取图片的保存路径                        string fileName=moveImage(imagePath+"/"+row[rxf.fieldRemark],node.ImageSavePath);                        //判断是否正确移动图片                        if (fileName == null || fileName.Equals(string.Empty))                        {                            sb = rowReport(sb, ds, row, "图片路径可能有错,请核查");                            isError = true;                            break;                        }                        property.SetValue(obj1, Convert.ChangeType(fileName, property.PropertyType), null);                        continue;                    }                    //是否需要转换值                    if (rxf.InvokeMethod != null)                    {                        //调用转换方法                        object[] par={row[rxf.fieldRemark]};                        try                        {                            object returnValue = invokeMethod(rxf.InvokeMethod, par);                            property.SetValue(obj1, Convert.ChangeType(returnValue, property.PropertyType), null);                        }                        catch (Exception ex)                        {                            sb = rowReport(sb, ds, row, ex.Message);                            isError = true;                            break;                        }                        continue;                    }                    if (rxf.isRelated)                    {                        string[] relatedFields = rxf.relatedField.Split(',');                        object[] par = new object[relatedFields.Length];                        for (int i = 0; i < relatedFields.Length; ++i)                        {                            par[i] = row[relatedFields[i]];                        }                        try                        {                            object returnValue = invokeMethod(rxf.relatedMethod, par);                            property.SetValue(obj1, Convert.ChangeType(returnValue, property.PropertyType), null);                        }                        catch (Exception ex)                        {                            sb = rowReport(sb, ds, row, ex.Message);                            isError = true;                            break;                        }                        continue;                    }                    try                    {                        property.SetValue(obj1, Convert.ChangeType(row[rxf.fieldRemark], property.PropertyType), null);                    }                    catch (Exception ex)                    {                        sb = rowReport(sb, ds, row, ex.Message);                        isError = true;                        break;                    }                                    }                if (isError == true)                {                    continue;                }                //保存数据到数据库                object[] parameters={obj1};                object isRightSave = invokeMethod(node.saveMethod, parameters);                if (Convert.ToString(isRightSave)!="true")                {                    sb = rowReport(sb, ds, row, Convert.ToString(isRightSave));                }                           }            return sb.ToString();        }        /// <summary>        /// 移动一张图片到指定目录        /// </summary>        /// <param name="image">需要移动的图片路径</param>        /// <param name="savePath">保存路径</param>        /// <returns></returns>        public static string moveImage(string image,string savePath)        {            try            {                string ImageSavePath = HttpContext.Current.Server.MapPath(savePath)+"/bigpic";                if(!System.IO.Directory.Exists(ImageSavePath))                    System.IO.Directory.CreateDirectory(ImageSavePath);                //产生新的文件名称                string fileName = DateTime.Now.ToFileTime() + System.IO.Path.GetExtension(image);                while (System.IO.File.Exists(ImageSavePath + "/" + fileName))//保证产生不会重复的文件名称                {                    fileName = DateTime.Now.ToFileTime() + System.IO.Path.GetExtension(image);                }                //移动文件                System.IO.File.Move(image, ImageSavePath + "/" + fileName);                //压缩图片                string smallPic=HttpContext.Current.Server.MapPath(savePath)+"/smallpic";                if(!System.IO.Directory.Exists(smallPic))                    System.IO.Directory.CreateDirectory(smallPic);                ImageCompress.compressionHeight(ImageSavePath + "/" + fileName, smallPic, 54);                return fileName;            }            catch(Exception ex)            {                logger.Error(string.Format("移动文件出错:"+ex.Message));                return null;            }        }        public static StringBuilder rowReport(StringBuilder sb, DataSet ds, DataRow row, string errMsg)        {            //验证是否为空行            bool isEmpty =true ;            foreach (DataColumn column in ds.Tables[0].Columns)            {                if (row[column.ColumnName].ToString().Trim() != "")                {                    isEmpty = false;                    break;                }            }            if (isEmpty)                return sb;            //记录            sb.Append("<tr>");            foreach (DataColumn column in ds.Tables[0].Columns)            {                sb.AppendFormat("<td>{0}</td>", row[column.ColumnName]);            }            sb.AppendFormat("<td>{0}</td>", Convert.ToString(errMsg));            sb.Append("</tr>");            return sb;        }        public static object invokeMethod(string spaceClassName, object[] parameters)        {            int index = spaceClassName.LastIndexOf('.');            //获取命名空间+类名            string className = spaceClassName.Substring(0, index);            //获取方法名            string methodName = spaceClassName.Substring(index + 1);            Type typeMethod = Type.GetType(className);            MethodInfo method = typeMethod.GetMethod(methodName);            if (method == null)                throw new Exception(string.Format("方法<{0}>未定义", spaceClassName));            object returnValue=null;            try            {               returnValue=method.Invoke(typeMethod.CreateInstanceDelegate(), parameters);            }            catch(ArgumentException ex)            {                parameters[0] = Convert.ToInt32(parameters[0]);                returnValue = method.Invoke(typeMethod.CreateInstanceDelegate(), parameters);            }            return returnValue;        }        public static string uploadImage(string path)        {            FileUpload file = new FileUpload();                        if (file.HasFile)            {                try                {                    //是否存在该目录                    path =HttpContext.Current.Server.MapPath(path);                    if (!System.IO.Directory.Exists(path))                    {                        System.IO.Directory.CreateDirectory(path);                    }                    //获取后缀名                    string extention = System.IO.Path.GetExtension(file.FileName);                    //得到不重名的文件名                    string fileName = DateTime.Now.ToFileTime().ToString() + extention;                    while (System.IO.File.Exists(path + "/" + fileName))                    {                        fileName = DateTime.Now.ToFileTime().ToString() + extention;                    }                    //上传文件                    file.SaveAs(path + "/" + fileName);                    return path + "/" + fileName;                }                catch (Exception ex)                {                    logger.Error( string.Format("上传文件失败,失败原因是:{0}", ex.Message));                    return null;                }            }            return string.Empty;        }        public static PropertyInfo getPropertyInfo(Type type, string propertyName)        {            PropertyInfo[] properties = type.GetProperties();            foreach (PropertyInfo property in properties)//给每个属性赋值            {                if (propertyName == property.Name)                {                    return property;                }            }            return null;        }        /// <summary>        /// 读取<itemName>节点对应的值        /// </summary>        /// <param name="itemName"></param>        /// <returns></returns>        public static readExcelMap getXmlMap(string itemName)        {            readExcelMap node=null ;            XmlDocument xmlDoc = new XmlDocument();            string xmlPath = HttpContext.Current.Server.MapPath("/common/readExcel.xml");            xmlDoc.Load(xmlPath);            XmlNodeList xmlNodes = xmlDoc.SelectSingleNode("Root").SelectNodes("Item");            foreach (XmlNode item in xmlNodes)            {                if (item.SelectSingleNode("ItemName").InnerText.Trim() != itemName)                    continue;                else                {                    node = new readExcelMap();                    node.fields = new List<readXmlField>();                    node.itemName = itemName;                    //获取保存方法                    node.saveMethod = item.SelectSingleNode("saveMethod").InnerText.Trim();                    if (item.SelectSingleNode("ImageSavePath")!=null)                        node.ImageSavePath = item.SelectSingleNode("ImageSavePath").InnerText.Trim();                    //获取属性                    XmlNodeList fields = item.SelectSingleNode("Fields").ChildNodes;                    foreach (XmlNode field in fields)                    {                        readXmlField rxf = new readXmlField();                        rxf.filedName = field.SelectSingleNode("FieldName").InnerText.Trim();                        XmlNode nodeRemark = field.SelectSingleNode("FiledRemark");                        if (nodeRemark != null)                            rxf.fieldRemark = nodeRemark.InnerText.Trim();                        else                            rxf.fieldRemark = null;                        rxf.isImageUrl = Convert.ToBoolean(field.SelectSingleNode("isImageUrl").InnerText.Trim());                        XmlNode im = field.SelectSingleNode("InvokeMethod");                        if (im != null)                        {                            rxf.InvokeMethod = im.InnerText.Trim();                        }                        else                            rxf.InvokeMethod = null;                        XmlNode isRelated = field.SelectSingleNode("IsRelated");                        if (isRelated != null)                            rxf.isRelated = Convert.ToBoolean(isRelated.InnerText.Trim());                        else                            rxf.isRelated = false;                        XmlNode relateFiled = field.SelectSingleNode("RelatedField");                        if (relateFiled != null)                            rxf.relatedField = relateFiled.InnerText.Trim();                        XmlNode relatedMethod = field.SelectSingleNode("RelatedMethod");                        if (relatedMethod != null)                            rxf.relatedMethod = relatedMethod.InnerText.Trim();                        node.fields.Add(rxf);                    }                }                            }            return node;        }        /// <summary>        /// 得到表格数据        /// </summary>        /// <param name="excelFile"></param>        /// <returns></returns>        public static DataSet getExcelData(string excelFile)        {            try            {                //连接数据源                string connectiongString = "provider=Microsoft.Jet.OLEDB.4.0; data source=" + excelFile + "; Extended Properties='Excel 8.0;HDR=YES;IMEX=1;'";                string sql = "select * from [Sheet1$]";                OleDbConnection con = new OleDbConnection(connectiongString);                if (con.State == ConnectionState.Closed)                {                    con.Open();                }                //获取数据                OleDbCommand com = new OleDbCommand(sql, con);                OleDbDataAdapter da = new OleDbDataAdapter(com);                DataSet ds = new DataSet();                da.Fill(ds);                return ds;            }            catch (Exception ex)            {                logger.Error(string.Format("获取表格数据失败,失败原因是:", ex.Message));                return null;            }        }    }

4、调用上传方法

//direcoryName 为excel存放的目录名称leadInReport = readExcel.leadIn<tab_question>(new tab_question(), name, direcoryName, "question");



这里有图片的话,我采取的方式是将excel文件和图片文件压缩为.zip格式文件,上传后把.zip格式的文件解压然后上传。解压的方法可以参考我的下一篇文章。


上面我大概讲了我的实现方法,如果你有更好的方法,希望能和我分享。

原创粉丝点击