#nullable enable using Furion.DatabaseAccessor; using Furion.FriendlyException; using System.ComponentModel; using System.Linq.Expressions; using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.Xml.Linq; namespace Admin.NET.Core { public static class DataConvertUtil { /// /// 将对象转换为Excel数据 /// /// /// /// /// /// /// /// public static void ToExcelData(List source, IRepository sysDictTypeRep, IRepository sysDictDataRep, out List headers, out List> data, out string sheetName) { headers = new List(); data = new List>(); var type = typeof(T); sheetName = ((DescriptionAttribute?)type.GetCustomAttribute(typeof(DescriptionAttribute), true))?.Description ?? "无"; List enumClassNames = new(); foreach (var field in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if ("Id".Equals(field.Name)) continue; if (field.Name.EndsWith("Id")) continue; headers.Add(((DescriptionAttribute?)field.GetCustomAttribute(typeof(DescriptionAttribute), true))?.Description ?? "无"); var dataType = StringUtil.ParseTrueType2(field.PropertyType.FullName ?? ""); if (TypeUtil.GetType(dataType)?.IsEnum ?? false) { if (!enumClassNames.Contains(dataType)) { enumClassNames.Add(dataType); } } } var dictTypeList = sysDictTypeRep.DetachedEntities.Where(x => enumClassNames.Contains(x.EnumClassName)).ToList(); List dictTypeIds = dictTypeList.Select(x => x.Id).ToList(); Dictionary dictTypeDictionary = new(); dictTypeList.ForEach(x => dictTypeDictionary.Add(x.Id, x)); var dictDataList = sysDictDataRep.DetachedEntities.Where(x => dictTypeIds.Contains(x.TypeId)).ToList(); dictDataList.ForEach(x => { if (dictTypeDictionary.ContainsKey(x.TypeId)) { var dictType = dictTypeDictionary[x.TypeId]; if (dictType?.SysDictDatas == null) { if (dictType != null) { dictType.SysDictDatas = new List(); } } dictType?.SysDictDatas?.Add(x); } }); Dictionary map = new(); dictTypeList.ForEach(x => { if (x?.SysDictDatas != null) { foreach (SysDictData dictData in x.SysDictDatas) { if (dictData != null) map.Add(x.EnumClassName + "#" + dictData.Code, dictData.Value); } } }); foreach (var t in source) { List objectList = new(); foreach (var field in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var fieldName = field.Name; if ("Id".Equals(fieldName)) continue; if (field.Name.EndsWith("Id")) continue; var v = t?.GetType()?.GetProperty(fieldName)?.GetValue(t); var dataType = StringUtil.ParseTrueType2(field.PropertyType.FullName ?? ""); if (TypeUtil.GetType(dataType)?.IsEnum ?? false) { v = Convert.ToInt32(v); if (map.ContainsKey(dataType + "#" + v)) v = map[dataType + "#" + v]; } else if ("System.DateTimeOffset".Equals(dataType)) { v = ExcelDateUtil.ToInt( new DateTimeOffset(Convert.ToDateTime(((DateTimeOffset?)v)?.ToString("yyyy-MM-dd") ?? "1900-01-01"))); } else if ("System.DateTime".Equals(dataType)) { v = ExcelDateUtil.ToInt( Convert.ToDateTime(((DateTime?)v)?.ToString("yyyy-MM-dd") ?? "1900-01-01")); } objectList.Add(v ?? ""); } data.Add(objectList); } } /// /// 将对象转换为Excel数据 /// /// /// /// /// /// /// /// /// public static void ToExcelData(List source, IRepository sysDictTypeRep, IRepository sysDictDataRep, out List headers, out List> data, out string sheetName, out string className) { ToExcelData(source, sysDictTypeRep, sysDictDataRep, out headers, out data, out sheetName); var type = typeof(T); className = type.Name ?? ""; if (className.EndsWith("Output")) { className = className[..^"Output".Length]; } } /// /// 根据键数字生成内容字符串 /// /// /// /// /// public static string ParseStrByKeys(this T t, string[] keys) { var type = typeof(T); Dictionary namePropertyInfoDict = new(); foreach (var field in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var fName = field?.Name ?? ""; if (keys.Contains(fName)) { namePropertyInfoDict[fName] = field ?? null!; } } var str = ""; foreach (var k in keys) { str += StringUtil.SplitChar() + namePropertyInfoDict[k]?.GetValue(t) ?? ""; } return str; } /// /// 将Excel数据转换为对象列表 /// /// /// /// /// /// public static List ToObjectList(List headers, List> data, string sheetName, string[] keys, int dataStartLine, out Dictionary dict) { var type = typeof(T); //去掉此验证 【Editby shaocx,2024-04-15】 //var sheetName2 = ((DescriptionAttribute?)type.GetCustomAttribute(typeof(DescriptionAttribute), true))?.Description ?? "无"; //if (!sheetName2.Equals(sheetName)) //{ // throw Oops.Oh(ErrorCode.Excel003); //} Dictionary indexFieldNameDict = new(); Dictionary indexFieldTypeDict = new(); Dictionary indexPropertyInfoDict = new(); Dictionary namePropertyInfoDict = new(); foreach (var field in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var desc = ((DescriptionAttribute?)field.GetCustomAttribute(typeof(DescriptionAttribute), true))?.Description ?? "无"; var fName = field.Name ?? ""; var fType = StringUtil.ParseTrueType2(field.PropertyType.FullName ?? ""); for (var i = 0; i < headers.Count; i++) { var header = headers[i]; if (header.Equals(desc)) { indexFieldNameDict[i] = fName; indexFieldTypeDict[i] = fType; indexPropertyInfoDict[i] = field; namePropertyInfoDict[fName] = field; break; } } } List outputs = new(); foreach (var record in data) { var output = Activator.CreateInstance(type, true); for (var i = 0; i < record.Count; i++) { if ("System.String".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, record[i]?.ToString() ?? "", null); } else if ("System.Int32".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, int.Parse(record[i]?.ToString() ?? "0"), null); } else if ("System.Int64".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, long.Parse(record[i]?.ToString() ?? "0"), null); } else if ("System.Single".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, float.Parse(record[i]?.ToString() ?? "0.0"), null); } else if ("System.Double".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, double.Parse(record[i]?.ToString() ?? "0.0"), null); } else if ("System.Decimal".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, decimal.Parse(record[i]?.ToString() ?? "0.0"), null); } else if ("System.Boolean".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, bool.Parse(record[i]?.ToString() ?? "False"), null); } else if ("System.Byte".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, byte.Parse(record[i]?.ToString() ?? "0"), null); } else if (TypeUtil.GetType(indexFieldTypeDict[i])?.IsEnum ?? false) { indexPropertyInfoDict[i].SetValue(output, TypeUtil.GetType(indexFieldTypeDict[i])?.GetEnumByDescription(record[i]?.ToString() ?? ""), null); } else if ("System.DateTime".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, ExcelDateUtil.ToDateTime(long.Parse(record[i]?.ToString() ?? "1")), null); } else if ("System.DateTimeOffset".Equals(indexFieldTypeDict[i])) { indexPropertyInfoDict[i].SetValue(output, ExcelDateUtil.ToDateTimeOffset(long.Parse(record[i]?.ToString() ?? "1")), null); } } if (output != null) { outputs.Add((T)output); } } dict = new Dictionary(); foreach (var x in outputs) { var key = string.Empty; foreach (var k in keys) { key += StringUtil.SplitChar() + namePropertyInfoDict[k]?.GetValue(x) ?? ""; } if (!string.IsNullOrEmpty(key)) { if (dict.ContainsKey(key)) throw Oops.Oh($"在{sheetName}页的第{dataStartLine}行, 唯一键冲突"); dict.Add(key, x); } dataStartLine += 1; }; return outputs; } /// /// 获取已存在的数据 /// /// /// /// public static List> ParseUniqueKeyValueDictList(this List records, List keys, int dataStartLine, string sheetName) { if (keys.Count <= 0) { throw Oops.Oh(ErrorCode.Key001); } if (records.Count <= 0) { return new List>(); } Type type = typeof(T); List> uniqueKeyValueDictList = new(); var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => keys.Contains(x.Name)).ToList(); Dictionary namePropDict = new(); props.ForEach(x => namePropDict.Add(x.Name, x)); List keyStrs = new(); records.ForEach(x => { Dictionary dict = new(); string keyStr = string.Empty; keys.ForEach(y => { var value = namePropDict[y]?.GetValue(x) ?? ""; if (string.IsNullOrWhiteSpace(value + "")) throw Oops.Oh($"在{sheetName}页的第{dataStartLine}行, {y}的取值不能为空"); keyStr += StringUtil.SplitChar() + value; dict.Add(y, value); }); if (keyStrs.Contains(keyStr)) throw Oops.Oh($"在{sheetName}页的第{dataStartLine}行, 唯一键冲突"); keyStrs.Add(keyStr); uniqueKeyValueDictList.Add(dict); dataStartLine++; }); return uniqueKeyValueDictList; } /// /// 生成动态查询已存在记录的lamda表达式列表 /// /// /// /// /// /// public static List>> GetExpressionListByUniqueDict(List keys, List> uniqueKeyValueDictList, int size) { if (keys.Count <= 0) throw Oops.Oh(ErrorCode.Key001); var uniqueKeyValueDictListArray = uniqueKeyValueDictList.SplitList(size); Type type = typeof(T); var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => keys.Contains(x.Name)).ToList(); Dictionary namePropDict = new(); props.ForEach(x => namePropDict.Add(x.Name, x)); List>> filters = new(); foreach (var dictList in uniqueKeyValueDictListArray) { var parameter = Expression.Parameter(type, "m"); Expression? expression = null; foreach (var item in dictList) { Expression? expressionItem = null; foreach (var key in keys) { Expression expProperty = Expression.Property(parameter, key); Expression> valueLamda = () => item[key]; Expression expValue = Expression.Convert(valueLamda.Body, namePropDict[key].PropertyType); expressionItem = expressionItem == null ? Expression.Equal(expProperty, expValue) : Expression.AndAlso(expressionItem, Expression.Equal(expProperty, expValue)); } expression = (expression == null) ? expressionItem : Expression.OrElse(expression, expressionItem ?? null!); } Expression> filter = ((Expression>)Expression.Lambda(expression ?? null!, parameter)); filters.Add(filter); } return filters; } /// /// 生成动态查询已存在记录的投影lamda表达式列表 /// /// /// /// /// public static Expression> GetSelectExpressionListByUniqueDict(List keys) { if (keys.Count <= 0) { throw Oops.Oh(ErrorCode.Key001); } Type type = typeof(TSource); var left = Expression.Parameter(type, "x"); var v0 = Expression.New(typeof(TResult)); List bindingList = new(); foreach (var item in keys) { MemberInfo speciesMember = typeof(TResult).GetMember(item)[0]; MemberExpression mem = Expression.Property(left, item); MemberBinding memberBinding = Expression.Bind(speciesMember, mem); bindingList.Add(memberBinding); } Expression body = Expression.MemberInit(v0, bindingList); Expression> selector = (Expression>)Expression.Lambda(body, left); return selector; } /// /// 获取字典生成的键字符串 /// /// /// /// /// public static string GetKey(T t, string[] keys) { Type type = typeof(T); List> uniqueKeyValueDictList = new(); var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => keys.Contains(x.Name)).ToList(); Dictionary namePropDict = new(); props.ForEach(x => namePropDict.Add(x.Name, x)); string key = ""; foreach (var item in keys) { key += StringUtil.SplitChar() + namePropDict[item]?.GetValue(t) ?? ""; } return key; } } }