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.定義類(假設是用戶信息)this

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

自定義特定來標識這兩個信息不能爲空spa

3.實現excel

/// <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數組是爲了代碼重用。最後那段泛型、非泛型判斷能夠刪除,估計通常用不到code

相關文章
相關標籤/搜索