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