/// <summary> /// 解析单个值 /// </summary> /// <param name="type"></param> /// <param name="typeDefined"></param> /// <param name="attributes"></param> /// <param name="jsonValue"></param> /// <param name="report"></param> /// <returns></returns> private static object ParseSingleValue(string type, object typeDefined, AttributeTable attributes, JsonParser.JsonValueContext jsonValue, ReportWrap report) { if (typeDefined is Enum) { return(ParseEnum(typeDefined as Enum, jsonValue, report)); } else if (typeDefined is Struct) { return(ParseStruct(typeDefined as Struct, jsonValue, report)); } else if (typeDefined is Table) { return(ParseTable(typeDefined as Table, jsonValue, report)); } else if (BaseUtil.IsBaseType(type)) { return(ParseScalar(type, jsonValue, report)); } return(null); }
private static void ParseTable(Table table, CsvTable dataset, CSV csv) { var titleRowIndex = csv.titleRow - 1; var dataBeginRowIndex = csv.dataBeginRow - 1; var columnName2ColumnIndex = new Dictionary <string, int>(); //验证标题行有效性 if (titleRowIndex < 0 || titleRowIndex >= dataset.Count) { LogError(csv.filePath, titleRowIndex, -1, "标题行不存在!"); return; } //验证数据起始行有效性 if ((dataBeginRowIndex < 0 || dataBeginRowIndex >= dataset.Count)) { LogError(csv.filePath, dataBeginRowIndex, -1, "数据起始行不存在!"); return; } //检查标题行是否有重复的列名 CsvRow titleRow = dataset[titleRowIndex]; for (int i = 0; i < titleRow.Count; i++) { string colName = titleRow[i].text != null ? titleRow[i].text.Trim() : ""; if (string.IsNullOrEmpty(colName)) { continue; } if (columnName2ColumnIndex.ContainsKey(colName)) { LogError(csv.filePath, titleRowIndex, i, string.Format("标题行有重复列名:{0}!", colName)); } else { columnName2ColumnIndex.Add(colName, i); } } //检查标题行是否有有效数据 if (columnName2ColumnIndex.Count == 0) { LogError(csv.filePath, titleRowIndex, -1, "标题行没有有效的数据!"); return; } //检测数据表中是否缺少字段 foreach (var field in table.Fields) { var fieldName = field.DataField; if (!columnName2ColumnIndex.ContainsKey(fieldName)) { LogError(csv.filePath, titleRowIndex, -1, string.Format("标题行缺少名为\"{0}\"的列!", fieldName)); } } //找出所有带索引的列 var indexKeys = new HashSet <string>(); foreach (var index in table.Attributes.GetAttributes <Index>()) { foreach (var indexKey in index.IndexFields) { foreach (var field in table.Fields) { if (field.Name.Equals(indexKey)) { indexKeys.Add(field.DataField); } } } } //转换数据 for (int i = dataBeginRowIndex; i < dataset.Count; i++) { //忽略空行 if (dataset[i].isEmpty) { LogWarning(csv.filePath, i, -1, "整行内容为空,忽略!"); continue; } foreach (var field in table.Fields) { string fieldName = field.DataField; object fieldValue = null; object fieldDefaultValue = field.DefaultValue; if (!columnName2ColumnIndex.ContainsKey(fieldName) || (columnName2ColumnIndex[fieldName] < 0 || columnName2ColumnIndex[fieldName] >= dataset[i].Count)) { //缺少对应的数据列 | 列索引超出数据行总列数 if (BaseUtil.IsBaseType(field.Type)) { fieldValue = BaseUtil.GetDefaultValue(field.Type, fieldDefaultValue); } } else { bool isIndex = indexKeys.Contains(fieldName); bool isUnique = field.Attributes.GetAttribute <Unique>() != null; bool isNullable = field.Attributes.HasAttribute <Nullable>(); int columnIndex = columnName2ColumnIndex[fieldName]; CsvCol column = dataset[i][columnIndex]; string columnText = column.text; bool isEmpty = string.IsNullOrEmpty(columnText); if (BaseUtil.IsBaseType(field.Type)) { if (field.IsArray) { } else { object scalarValue = null; if (isEmpty) { if (!isNullable) { LogError(csv.filePath, i, columnIndex, string.Format("列{0}不允许为空!", fieldName)); } if (isUnique) { LogError(csv.filePath, i, columnIndex, string.Format("列{0}有唯一性约束,不允许为空!", fieldName)); } if (isIndex) { LogError(csv.filePath, i, columnIndex, string.Format("列{0}有索引,不允许为空!", fieldName)); } scalarValue = BaseUtil.GetDefaultValue(field.Type, fieldDefaultValue); } else { scalarValue = BaseUtil.GetScalar(field.Type, columnText); if (scalarValue == null) { LogError(csv.filePath, i, columnIndex, string.Format("'{0}'无法转换成一个'{1}'!", columnText, field.Type)); } } } } else if (field.TypeDefined is Model.Struct) { } else if (field.TypeDefined is Model.Enum) { } } } } }
/// <summary> /// 数组 /// </summary> /// <param name="attributes"></param> /// <param name="type"></param> /// <param name="typeDefined"></param> /// <param name="cellData"></param> /// <param name="errors"></param> /// <returns></returns> private object GetArray(AttributeTable attributes, string type, object typeDefined, ICell cellData, List <string> errors) { string cellText = null; if (cellData == null || cellData.CellType == CellType.Blank) { cellText = ""; } else if (cellData.CellType == CellType.String) { cellText = cellData.StringCellValue.Trim(); } else if (cellData.CellType == CellType.Numeric) { cellText = cellData.NumericCellValue.ToString(); } else if (cellData.CellType == CellType.Boolean) { cellText = cellData.BooleanCellValue.ToString(); } if (cellText == null) { cellText = ""; errors.Add(string.Format("内容无法转换成有效的{0}数组。", type)); } cellText = cellText.Trim(); var separator = ","; var arrayValue = attributes.GetAttribute <ArrayLiteral>(); if (arrayValue != null) { separator = arrayValue.separator; if (cellText.StartsWith(arrayValue.beginning)) { cellText = cellText.Substring(arrayValue.beginning.Length); } if (cellText.EndsWith(arrayValue.ending)) { cellText = cellText.Substring(0, cellText.Length - arrayValue.ending.Length); } } var texts = string.IsNullOrEmpty(cellText) ? new string[] { } : cellText.Split(new string[] { separator }, StringSplitOptions.None); if (BaseUtil.IsBaseType(type)) { return(BaseUtil.GetScalarArray(type, texts, errors)); } else if (typeDefined is Model.Enum) { return(BaseUtil.GetEnumArray(typeDefined as Model.Enum, texts, errors)); } else if (typeDefined is Model.Struct) { return(BaseUtil.GetStructArray(attributes, typeDefined as Model.Struct, texts, errors)); } return(null); }
public override void Read(Table table) { var xls = table.Attributes.GetAttribute <XLS>(); var filePath = xls.filePath; var sheetName = xls.sheetName; var titleRowIndex = xls.titleRow - 1; var dataBeginRowIndex = xls.dataBeginRow - 1; var dataSet = new List <object[]>(); var dataSetWidth = table.Fields.Count; var indexKeys = new HashSet <string>(); foreach (var index in table.Attributes.GetAttributes <Index>()) { foreach (var dataKey in index.IndexFields) { foreach (var field in table.Fields) { if (field.Name.Equals(dataKey)) { indexKeys.Add(field.DataField); } } } } var dataKeyList = new List <string>(); var dataKey2FieldSchema = new Dictionary <string, TableField>(); foreach (var field in table.Fields) { dataKeyList.Add(field.DataField); dataKey2FieldSchema.Add(field.DataField, field); } using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { var ext = Path.GetExtension(filePath).ToLower(); IWorkbook workbook = null; if (ext == ".xlsx") { workbook = new XSSFWorkbook(stream); } else if (ext == ".xls") { workbook = new HSSFWorkbook(stream); } else { ReportXlsError("未知的文件类型!", filePath); return; } var sheet = workbook.GetSheet(sheetName); if (sheet == null) { ReportXlsError("文件未找到表:" + sheetName + "。", filePath, sheetName); return; } var titleRow = sheet.GetRow(titleRowIndex); if (titleRow == null) { ReportXlsError("标题行不存在,无法导出。", filePath, sheetName, titleRowIndex); return; } var fieldName2CellIndex = new Dictionary <string, int>(); var cellIndex2FieldName = new Dictionary <int, string>(); //title for (var i = 0; i <= titleRow.LastCellNum; i++) { var cell = titleRow.GetCell(i); if (cell == null || cell.CellType == CellType.Blank) { continue; } if (cell.CellType == CellType.String) { if (fieldName2CellIndex.ContainsKey(cell.StringCellValue)) { ReportXlsError("标题列名重复出现。", filePath, sheetName, titleRowIndex, i); } else { fieldName2CellIndex.Add(cell.StringCellValue, i); cellIndex2FieldName.Add(i, cell.StringCellValue); } } else { ReportXlsError("标题列内容不是字符格式。", filePath, sheetName, titleRowIndex, i); } } foreach (var fieldName in dataKey2FieldSchema.Keys) { if (!fieldName2CellIndex.ContainsKey(fieldName)) { ReportXlsError("标题行中未找到列 " + fieldName + "。", filePath, sheetName, titleRowIndex); } } //data var uniqueChecker = new Dictionary <int, Dictionary <object, List <int> > >(); for (var rowIndex = dataBeginRowIndex; rowIndex <= sheet.LastRowNum; rowIndex++) { var row = sheet.GetRow(rowIndex); if (row == null) { continue; } var colCount = 0; for (var j = 0; j < dataKeyList.Count; j++) { if (fieldName2CellIndex.ContainsKey(dataKeyList[j])) { var cellData = row.GetCell(fieldName2CellIndex[dataKeyList[j]]); if (cellData != null && cellData.CellType != CellType.Blank) { colCount++; } } } if (colCount == 0) { continue; } var dataSetRow = new object[dataSetWidth]; for (var j = 0; j < dataKeyList.Count; j++) { var linkName = dataKeyList[j]; if (!fieldName2CellIndex.ContainsKey(linkName)) { continue; } var cellIndex = fieldName2CellIndex[linkName]; var cellData = row.GetCell(cellIndex); var field = dataKey2FieldSchema[linkName]; var isUnique = field.Attributes.GetAttribute <Unique>() != null; var isBaseType = BaseUtil.IsBaseType(field.Type) && field.TypeDefined == null; string fieldError = null; object fieldValue = null; var errors = new List <string>(); if (field.IsArray) { fieldValue = GetArray(field.Attributes, field.Type, field.TypeDefined, cellData, errors); } else { if (field.TypeDefined is Model.Struct) { fieldValue = GetStruct(field.Attributes, field.TypeDefined as Struct, cellData, errors); } else if (field.TypeDefined is Model.Enum) { fieldValue = GetEnum(field.TypeDefined as Model.Enum, cellData, errors); } else if (isBaseType) { var isIndex = indexKeys.Contains(field.DataField); var isNullable = field.Attributes.HasAttribute <Model.Attributes.Nullable>(); var defaultValue = field.DefaultValue; if (cellData == null || cellData.CellType == CellType.Blank) { if (!isNullable || isUnique) { errors.Add(String.Format("内容不允许为空!")); } else if (isIndex) { errors.Add(String.Format("索引字段不允许为空!")); } else { fieldValue = defaultValue != null ? defaultValue : 0; } } else if (BaseUtil.IsBaseType(field.Type)) { fieldValue = GetScalar(field.Type, cellData, errors); } } } if (errors.Count > 0) { fieldError = string.Join("\n", errors); } if (fieldError != null) { ReportXlsError(fieldError, filePath, sheetName, rowIndex, cellIndex); } dataSetRow[j] = fieldValue; if (isBaseType && isUnique && fieldValue != null) { if (!uniqueChecker.ContainsKey(cellIndex)) { uniqueChecker.Add(cellIndex, new Dictionary <object, List <int> >()); } if (!uniqueChecker[cellIndex].ContainsKey(fieldValue)) { uniqueChecker[cellIndex].Add(fieldValue, new List <int>()); } uniqueChecker[cellIndex][fieldValue].Add(rowIndex); } } dataSet.Add(dataSetRow); } foreach (var cellIndex in uniqueChecker.Keys) { var formatedCellIndex = FormatXlsColumnName(cellIndex); foreach (var val in uniqueChecker[cellIndex].Keys) { if (uniqueChecker[cellIndex][val].Count > 1) { var txts = new List <string>(); var firstRowIndex = uniqueChecker[cellIndex][val][0]; foreach (var rowIndex in uniqueChecker[cellIndex][val]) { txts.Add((rowIndex + 1).ToString() + "行"); } ReportXlsError(String.Format("{0} 列在 {1} 出现了相同的内容:\"{2}\"。", cellIndex2FieldName[cellIndex], string.Join(",", txts), val), filePath, sheetName); } } } } }