本质: excel资源-》数据库
场景: 用户上传个excel 想把这里面数据 存数据库
流程:1 校验数据 2.将可用数据进行保存
如图客户要上传的excel相关信息
C# 代码
1.获取
[HttpPost]
public HttpResponseMessage ImportActivityCheck()
{
Response<object> response = new Response<object>();
var file = HttpContext.Current.Request.Files[0]; //获取选中文件
if (file != null && file.ContentLength > 0)
{
//2 转DataSet
var ds = ExcelHelper.ExcelToDataSet(file.InputStream);
//3验证数据有效性
var result = BasicLevelService.ImportActivityCheck(ds.Tables[0]);
//4 返回有效结果进行预览如果没有客户预览 就直接保存即可
response.Result = result;
}
return JsonHelper.Instance.HttpResponse(response);
}
2. Excel转DataSet /datatable
/// <summary>
/// NPOI Excel转DataSet
/// </summary>
/// <param name="excelServerPath"></param>
/// <param name="hasTitle">是否有标题</param>
/// <param name="isRemoveEmptyRow">是否移除空行</param>
/// <returns></returns>
public static DataSet ExcelToDataSet(Stream stream, bool hasTitle = true)
{
IWorkbook workBook = WorkbookFactory.Create(stream, ImportOption.All);
DataSet ds = new DataSet();
for (int i = 0; i < workBook.NumberOfSheets; i++)
{
ISheet sheet = workBook.GetSheetAt(i);
DataTable dt = null;
if (hasTitle)
{
dt = SheetToDataTableHasTitle(sheet);
}
else
{
dt = SheetToDataTable(sheet);
}
ds.Tables.Add(dt);
}
return RemoveEmptyRow(ds);
}
3:进行数据检验 大多数情况 会预览让客户知道 如图 匹配情况
所以我们将匹配的集合返回 然后把不匹配的数量也返回
/// <summary>
/// 活动导入数据验证
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public List<ImportActivityCheckDto> ImportActivityCheck(DataTable dt)
{
if (dt.Rows.Count == 0) throw new Exception("无导入数据");
var result = new List<ImportActivityCheckDto>();
var idCardArr = new ArrayList();
foreach (DataRow row in dt.Rows)
{
try
{
var entity = new ImportActivityCheckDto()
{
IdCard = row["身份证号"].ToString(),
Name = row["姓名"].ToString(),
Title = row["活动名称"].ToString(),
TypeText = row["活动类型"].ToString(),
StartDate = DateTime.FromOADate(double.Parse(row["活动参与时间"].ToString()))
};
idCardArr.Add(entity.IdCard);
result.Add(entity);
}
catch (Exception e)
{
var entity = new ImportActivityCheckDto()
{
IdCard = row["身份证号"].ToString(),
Name = row["姓名"].ToString(),
Title = row["活动名称"].ToString(),
TypeText = row["活动类型"].ToString(),
StartDate = null
};
idCardArr.Add(entity.IdCard);
result.Add(entity);
}
}
string sql = $"select Id,IdCard,LastRestTime from MHBasicLevelCadre where IdCard in ('{string.Join("','", idCardArr.ToArray())}')";
var levelCadres = this.MHBasicLevelCadreApp.Repository.SqlQuery<ActivityCheckDto>(sql).ToList();
var activityList = Enumeration.GetAll<ActivityEnum>().ToList();
foreach (var item in result)
{
var entity = levelCadres.FirstOrDefault(c => c.IdCard == item.IdCard);
//找不到人
if (entity == null)
{
item.MateResult = ActivityMateResultEnum.找不到人.Code;
item.ErrorMsg = "档案无法匹配";
continue;
}
var typeEntity = activityList.FirstOrDefault(c => c.Name == item.TypeText);
//类型不匹配
if (typeEntity == null)
{
item.MateResult = ActivityMateResultEnum.类型无法匹配.Code;
item.ErrorMsg = "活动类型无法匹配";
continue;
}
item.Type = typeEntity.Code;
var count = result.Count(c => c.Type == item.Type && c.IdCard == item.IdCard && c.StartDate == item.StartDate);
//时间冲突
if (count > 1||item.StartDate==null)
{
item.MateResult = ActivityMateResultEnum.数据重复.Code;
item.ErrorMsg = "时间冲突";
continue;
}
item.CadreId = entity.Id;
item.MateResult = ActivityMateResultEnum.成功.Code;
}
return result;
}
4:预览过后 客户可能会修改数据 或者 执意要保存
但是这时候保存的数据就是前端把数据给到后端来了,所以只是将数据保存操作即可
如果没有客户预览的过程 那就 直接在第3步骤 直接保存那些有效的即可 不用传给前端预览 也就不会有第4步骤 在传回来保存的操作了