• NPOI+反射+自定义特性实现上传excel转List及验证


    1.自定义特性

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
        public class PropertyDescriptionAttribute : Attribute
        {
            private bool _allownullorempty = true;
            public PropertyDescriptionAttribute() { }
            /// <summary>
            /// 是否允许为null或空值
            /// </summary>
            public bool AllowNullOrEmpty
            {
                get
                {
                    return this._allownullorempty;
                }
                set
                {
                    this._allownullorempty = value;
                }
            }
        }

    2.定义类(假设是用户信息)

    public class UploadUserModel
        {
            [PropertyDescription(AllowNullOrEmpty = false)]
            public string Name { get; set; }
            [PropertyDescription(AllowNullOrEmpty = false)]
            public string Phone { get; set; }
        }

    自定义特定来标识这两个信息不能为空

    3.实现

    /// <summary>
    /// PROPERTY_NAME数组:值与excel列一一对应
    /// </summary>
    private readonly string[] PROPERTY_NAME = { "Name", "Phone" };
    
    private List<UploadUserModel> ExcelToList(HttpPostedFile excelFile)
            {
                IWorkbook workbook = null;
                ISheet sheet = null;
                int colCount = 0;
                List<UploadUserModel> users = new List<UploadUserModel>();
                if (excelFile.FileName.IndexOf(".xlsx") > 0)
                {
                    workbook = new XSSFWorkbook(excelFile.InputStream);
                }
                else if (excelFile.FileName.IndexOf(".xls") > 0)
                {
                    workbook = new HSSFWorkbook(excelFile.InputStream);
                }
                if (workbook != null)
                {
                    sheet = workbook.GetSheetAt(0);
                    if (sheet != null && sheet.LastRowNum > 0)
                    {
                        colCount = sheet.GetRow(0).LastCellNum;//获取列数                    
                        //从第二行开始解析
                        for (int rowIndex = 1; rowIndex <= sheet.LastRowNum; rowIndex++)
                        {
                            var curRow = sheet.GetRow(rowIndex);//获取当前行                       
                            UploadUserModel user = new UploadUserModel();
                            Type cType = user.GetType();
                            //解析列
                            for (int colIndex = 0; colIndex < colCount; colIndex++)
                            {
                                var curCell = curRow.GetCell(colIndex);
                                if (curCell != null)
                                {
                                    curCell.SetCellType(CellType.String);//把单元格设置成String类型,统一取值方式
                                }
                                //定义PROPERTY_NAME避免if判断
                                PropertyInfo propertyInfo = cType.GetProperty(PROPERTY_NAME[colIndex]);
                                //获取自定义特性
                                object[] customAttrs = propertyInfo.GetCustomAttributes(typeof(PropertyDescriptionAttribute), true);
                                if (customAttrs.Length > 0)
                                {
                                    PropertyDescriptionAttribute attr = customAttrs[0] as PropertyDescriptionAttribute;
                                    if (!attr.AllowNullOrEmpty)//属性值不能为空
                                    {
                                        if (curCell == null)
                                        {
                                            throw new Exception("" + (rowIndex + 1).ToString() + "行有未填项,请填写后重新上传。");
                                        }
                                        else if (string.IsNullOrEmpty(curCell.StringCellValue))
                                        {
                                            throw new Exception("" + (rowIndex + 1).ToString() + "行有未填项,请填写后重新上传。");
                                        }
                                    }
                                    object cellValue = null;
                                    if (curCell == null)
                                    {
                                        cellValue = "";
                                    }
                                    else
                                    {
                                        cellValue = curCell.StringCellValue;
                                    }
                                    if (!propertyInfo.PropertyType.IsGenericType)
                                    {
                                        //非泛型
                                        propertyInfo.SetValue(user, curCell == null ? null : Convert.ChangeType(cellValue, propertyInfo.PropertyType), null);
                                    }
                                    else
                                    {
                                        //泛型Nullable<>
                                        Type genericTypeDefinition = propertyInfo.PropertyType.GetGenericTypeDefinition();
                                        if (genericTypeDefinition == typeof(Nullable<>))
                                        {
                                            propertyInfo.SetValue(user, curCell == null ? null : Convert.ChangeType(cellValue, Nullable.GetUnderlyingType(propertyInfo.PropertyType)), null);
                                        }
                                    }
                                }                            
                            }
                            users.Add(user);
                        }
                    }
                }
                else
                {
                    throw new Exception("Excel解析异常");
                }
                foreach (var item in users)
                {
                    if (!checkPhoneGS(item.Phone))
                    {
                        throw new Exception("手机号格式不正确:"+ item.Phone);
                    }
                }
                return users;
            }

    不要看着麻烦,核心代码很简单。用反射和定义PROPERTY_NAME数组是为了代码重用。最后那段泛型、非泛型判断可以删除,估计一般用不到

  • 相关阅读:
    spring管理hibernate,mybatis,一级缓存失效原因
    The constructor ClassPathXmlApplicationContext(String) refers to the missing type BeansException
    idea中Hibernate错误:无法解析表
    使用Dom4解析xml
    关于idea中新建web项目 webapp文件夹没有小蓝点 ,启动服务,访问不到解决方案
    解决VS编译太慢问题
    Entity FrameWork6 Code First带virtual关键字外键 Asp.Net WebApi无法返回实体类数据问题
    webapi请求返回{"$id":"1","Message":"请求的资源不支持 http 方法“GET”。"}
    WPF的BusyIndicator控件只显示遮罩层,不显示提示层问题
    [转]Mysql将数据分组后取出时间最近的数据
  • 原文地址:https://www.cnblogs.com/betterlife/p/9360707.html
Copyright © 2020-2023  润新知