304 lines
13 KiB
C#
304 lines
13 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using MyCode.Project.Infrastructure.Common;
|
||
using MyCode.Project.Infrastructure.Exceptions;
|
||
|
||
namespace MyCode.Project.Infrastructure.Imports
|
||
{
|
||
/// <summary>
|
||
/// 导入配置类
|
||
/// </summary>
|
||
/// <typeparam name="T">实体类型</typeparam>
|
||
public class ImportConfig<T> where T : class, new()
|
||
{
|
||
/// <summary>
|
||
/// 导入的数据文件,转换为Excel操作实体
|
||
/// </summary>
|
||
public ExcelUtils ExcelUtil { get; set; }
|
||
|
||
/// <summary>
|
||
/// Excel中的标题和实体属性中的字段map,例如:标题->Title
|
||
/// </summary>
|
||
public List<ImportProperty> Properties { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 默认的属性列,这些列不需要Excel导入,而是程序中或者导入逻辑中直接设定
|
||
/// </summary>
|
||
public List<DefaultValueProperty> DefaultProperties { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 复杂类型的属性列
|
||
/// </summary>
|
||
public List<ImportComplexProperty> ComplexProperties { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 二维数据的属性列
|
||
/// </summary>
|
||
public List<ImportSplitProperty> SplitProperties { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 子表数据的属性列
|
||
/// </summary>
|
||
public List<ImportListProperty> ListProperties { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 初始化一个<see cref="ImportConfig{T}"/>类型的实例
|
||
/// </summary>
|
||
public ImportConfig()
|
||
{
|
||
Properties=new List<ImportProperty>();
|
||
DefaultProperties=new List<DefaultValueProperty>();
|
||
ComplexProperties=new List<ImportComplexProperty>();
|
||
SplitProperties=new List<ImportSplitProperty>();
|
||
ListProperties=new List<ImportListProperty>();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证Excel的导入格式是否正确
|
||
/// </summary>
|
||
/// <param name="message">消息</param>
|
||
/// <returns></returns>
|
||
public bool ValidFormat(ref string message)
|
||
{
|
||
//获取Excel的第一行数据,即标题
|
||
var columns = this.ExcelUtil.ExportFirstRowData();
|
||
foreach (var item in this.Properties)
|
||
{
|
||
//检查是否存在对应列
|
||
if (columns.All(x => x.Trim() != item.Caption))
|
||
{
|
||
message = string.Format("Excel中找不到[{0}]列!", item.Caption);
|
||
return false;
|
||
}
|
||
}
|
||
foreach (var item in this.ComplexProperties)
|
||
{
|
||
//检查是否存在对应列
|
||
if (columns.All(x => x.Trim() != item.Caption))
|
||
{
|
||
message = string.Format("Excel中找不到[{0}]列!", item.Caption);
|
||
return false;
|
||
}
|
||
}
|
||
foreach (var item in this.SplitProperties)
|
||
{
|
||
//检查是否存在对应列
|
||
if (columns.All(x => x.Trim() != item.Caption))
|
||
{
|
||
message = string.Format("Excel中找不到[{0}]列!", item.Caption);
|
||
return false;
|
||
}
|
||
}
|
||
foreach (var item in this.ListProperties)
|
||
{
|
||
//检查是否存在对应列
|
||
if (columns.All(x => x.Trim() != item.Caption))
|
||
{
|
||
message = string.Format("Excel中找不到[{0}]列!", item.Caption);
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将Excel数据转换为实体列表
|
||
/// </summary>
|
||
/// <param name="sourceData">数据源</param>
|
||
/// <returns></returns>
|
||
public List<T> GetListData(List<Dictionary<string, object>> sourceData)
|
||
{
|
||
var type = typeof(T);
|
||
List<T> resultData=new List<T>();
|
||
|
||
foreach (var item in sourceData)
|
||
{
|
||
T entity=new T();
|
||
object listItem = null;// 该对象用于存储子表数据
|
||
bool isAddList = false;// 判断是否增加子表数据
|
||
foreach (var prop in this.ListProperties)
|
||
{
|
||
var input = item[prop.Caption];
|
||
var keyValue = item[prop.PrimaryKeyCaption].ToString();
|
||
//验证格式
|
||
string message = "";
|
||
if (!prop.ValidateInput(input, ref message))
|
||
{
|
||
throw new BaseException(message);
|
||
}
|
||
//获取对应类型的值
|
||
var value = prop.GetValue(input);
|
||
|
||
var matersEntity =
|
||
resultData.FirstOrDefault(
|
||
p => type.GetProperty(prop.PrimaryKey).GetValue(p).ToString() == keyValue);
|
||
IList procList = null;
|
||
if (matersEntity != null)
|
||
{
|
||
procList = type.GetProperty(prop.ComplexPropName).GetValue(matersEntity, null) as IList;
|
||
//因为主表数据已经存在,所以这个时候只需要增加子表数据。后面的数据直接跳过
|
||
isAddList = true;
|
||
}
|
||
else
|
||
{
|
||
procList = type.GetProperty(prop.ComplexPropName).GetValue(entity, null) as IList;
|
||
if (procList == null)
|
||
{
|
||
//创建子表集合对象
|
||
var procType = prop.ComplexPropType;
|
||
var listType = typeof(List<>).MakeGenericType(procType);
|
||
procList = Activator.CreateInstance(listType) as IList;
|
||
//赋值
|
||
type.GetProperty(prop.ComplexPropName).SetValue(entity,procList,null);
|
||
}
|
||
}
|
||
|
||
if (listItem == null)
|
||
{
|
||
//创建一个目标类型的空实例
|
||
listItem = prop.ComplexPropType.Assembly.CreateInstance(prop.ComplexPropType.FullName);
|
||
//添加到子表集合中
|
||
procList.Add(listItem);
|
||
}
|
||
|
||
if (prop.ChildProperty != null)
|
||
{
|
||
var childEntity =
|
||
prop.ChildProperty.PropType.Assembly.CreateInstance(prop.ChildProperty.PropType.FullName);
|
||
prop.ChildProperty.PropType.GetProperty(prop.ChildProperty.EntityProp).SetValue(childEntity,value,null);
|
||
prop.ComplexPropType.GetProperty(prop.EntityProp).SetValue(listItem, childEntity, null);
|
||
}
|
||
else
|
||
{
|
||
prop.ComplexPropType.GetProperty(prop.EntityProp).SetValue(listItem,value,null);
|
||
}
|
||
}
|
||
|
||
if (isAddList)
|
||
{
|
||
//因为主表数据已经存在,所以这个时候只需要增加子表数据。后面的数据直接跳过
|
||
continue;
|
||
}
|
||
//设置基础值
|
||
foreach (var prop in this.Properties)
|
||
{
|
||
var input = item[prop.Caption];
|
||
//验证格式
|
||
string message = "";
|
||
if (!prop.ValidateInput(input, ref message))
|
||
{
|
||
throw new BaseException(message);
|
||
}
|
||
//获取对应类型的值
|
||
var value = prop.GetValue(input);
|
||
type.GetProperty(prop.EntityProp).SetValue(entity,value,null);
|
||
}
|
||
|
||
//设置默认值
|
||
foreach (var prop in this.DefaultProperties)
|
||
{
|
||
type.GetProperty(prop.EntityProp).SetValue(entity,prop.DefaultValue,null);
|
||
}
|
||
|
||
//设置复杂类型属性
|
||
foreach (var prop in this.ComplexProperties)
|
||
{
|
||
var input = item[prop.Caption];
|
||
//验证格式
|
||
string message = "";
|
||
if (!prop.ValidateInput(input, ref message))
|
||
{
|
||
throw new BaseException(message);
|
||
}
|
||
|
||
//获取对应类型的值
|
||
var value = prop.GetValue(input);
|
||
|
||
var propEntity = type.GetProperty(prop.ComplexPropName).GetValue(entity);
|
||
if (propEntity == null)
|
||
{
|
||
//创建一个目标类型的空实例
|
||
propEntity = prop.ComplexPropType.Assembly.CreateInstance(prop.ComplexPropType.FullName);
|
||
if (prop.ChildProperty != null)
|
||
{
|
||
var childEntity =
|
||
prop.ChildProperty.PropType.Assembly.CreateInstance(prop.ChildProperty.PropType.FullName);
|
||
prop.ChildProperty.PropType.GetProperty(prop.ChildProperty.EntityProp).SetValue(childEntity,value,null);
|
||
prop.ComplexPropType.GetProperty(prop.EntityProp).SetValue(propEntity, childEntity, null);
|
||
|
||
}
|
||
else
|
||
{
|
||
prop.ComplexPropType.GetProperty(prop.EntityProp).SetValue(propEntity,value,null);
|
||
}
|
||
//添加到实体中
|
||
type.GetProperty(prop.ComplexPropName).SetValue(entity,propEntity,null);
|
||
}
|
||
else
|
||
{
|
||
if (prop.ChildProperty != null)
|
||
{
|
||
var childEntity =
|
||
prop.ChildProperty.PropType.Assembly.CreateInstance(prop.ChildProperty.PropType.FullName);
|
||
prop.ChildProperty.PropType.GetProperty(prop.ChildProperty.EntityProp).SetValue(childEntity,value,null);
|
||
prop.ComplexPropType.GetProperty(prop.EntityProp).SetValue(propEntity, childEntity, null);
|
||
}
|
||
else
|
||
{
|
||
prop.ComplexPropType.GetProperty(prop.EntityProp).SetValue(propEntity, value, null);
|
||
}
|
||
}
|
||
}
|
||
|
||
//设置二维数据类型属性
|
||
foreach (var prop in this.SplitProperties)
|
||
{
|
||
var arrayData = item[prop.Caption].ToString().Split(',');
|
||
|
||
//创建对应的类型集合
|
||
var listType = typeof(List<>).MakeGenericType(prop.ComplexPropType);
|
||
var procList = Activator.CreateInstance(listType) as IList;
|
||
|
||
foreach (var propValue in arrayData)
|
||
{
|
||
var input = propValue;
|
||
//验证格式
|
||
string message = "";
|
||
if (!prop.ValidateInput(input, ref message))
|
||
{
|
||
throw new BaseException(message);
|
||
}
|
||
//获取对应类型的值
|
||
var value = prop.GetValue(input);
|
||
if (prop.ChildProperty != null)
|
||
{
|
||
var propEntity = prop.ComplexPropType.Assembly.CreateInstance(prop.ComplexPropType.FullName);
|
||
var childEntity =
|
||
prop.ChildProperty.PropType.Assembly.CreateInstance(prop.ChildProperty.PropType.FullName);
|
||
|
||
prop.ChildProperty.PropType.GetProperty(prop.ChildProperty.EntityProp).SetValue(childEntity, value, null);
|
||
prop.ComplexPropType.GetProperty(prop.EntityProp).SetValue(propEntity, childEntity, null);
|
||
procList.Add(propEntity);
|
||
}
|
||
else
|
||
{
|
||
var propEntity = prop.ComplexPropType.Assembly.CreateInstance(prop.ComplexPropType.FullName);
|
||
prop.ComplexPropType.GetProperty(prop.EntityProp).SetValue(propEntity, value, null);
|
||
procList.Add(propEntity);
|
||
}
|
||
}
|
||
|
||
//将集合添加到实体中
|
||
type.GetProperty(prop.ComplexPropName).SetValue(entity,procList,null);
|
||
}
|
||
resultData.Add(entity);
|
||
}
|
||
return resultData;
|
||
}
|
||
}
|
||
}
|