BOM表格的数据库导入--一种树形结构
BOM表的数据大体样式
设计的mysql 模型
要求:1.BOM表数据大概有1W~2W的量,导入效率优先级最高;2.代号存入物号表,前端有A0018是不能有重复数据的;
begin:基本思路就是:
1.划分BOM树的层级,一级的数据存入dictionary[0],二级的数据存入dictionary[1].....依次类推;
2.保存父级数据,如dictionary[0],(这里避免频繁打开数据库操作,用的StringBuilder sql = new StringBuilder();sql.Append(),拼成一个完成的MySql 语句存入数据库,StringBuilder 比 String 执行效率要快很多);
3.保存第二层级(子集时)
1 Hashtable table = 2 Plist.Where(p => p["oldNO"].ToString() == pidstr).First(); 3 int pid = Convert.ToInt32(table["BOMID"] + "");
遍历 第二层级的数据,用linq 语句查找每个的父级,对应上;
4.这里获取父级的ID,思路是 先一起保存,然后再一起查询出来,将需要的数据存入list<>集合中;
1 List<Hashtable> Tlist = new List<Hashtable>(); 2 if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) 3 { 4 for (int j = 0; j < ds.Tables[0].Rows.Count; j++) 5 { 6 DataRow drRows = ds.Tables[0].Rows[j]; 7 #region 存入集合 8 Hashtable table = new Hashtable(); 9 table.Add("BOMID", drRows["ID"]); 10 table.Add("oldNO", drRows["OldID"]); 11 Tlist.Add(table); 12 #endregion 13 } 14 } 15 return Tlist;
5.尽量减少循环里面套循环,一个循环,能对数据进行处理完,最好都放在同一个循环里面处理.
完整代码:
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Configuration; 5 using System.Data; 6 using System.Data.OleDb; 7 using System.Web; 8 using System.IO; 9 using System.Linq; 10 using NPOI.HSSF.UserModel; 11 using System.Text; 12 using System.Web.UI.WebControls; 13 using System.Xml.Schema; 14 15 16 namespace Md.Api.Web 17 { 18 /// <summary> 19 /// ExcelFileUploadHQL 的摘要说明 20 /// </summary> 21 public class ExcelFileUploadHQL : IHttpHandler 22 { 23 private static int CompID { get; set; } 24 private static int CreateUser { get; set; } 25 private static int ProjectID { get; set; } 26 private static string ProjectCode { get; set; } 27 28 private string Path 29 { 30 get 31 { 32 string path = ConfigurationManager.AppSettings["filepath"]; 33 34 try 35 { 36 path = HttpContext.Current.Server.MapPath(path); 37 } 38 catch (Exception) 39 { 40 } 41 return path; 42 } 43 } 44 45 /// <summary> 46 /// 接收请求 47 /// </summary> 48 /// <param name="context"></param> 49 public void ProcessRequest(HttpContext context) 50 { 51 string result = ""; 52 context.Response.ContentType = "text/plain"; 53 HttpPostedFile postFile = context.Request.Files["Filedata"]; 54 CompID = Convert.ToInt32(context.Request["CompID"] + ""); 55 CreateUser = Convert.ToInt32(context.Request["CreateUser"] + ""); 56 ProjectID = Convert.ToInt32(context.Request["ProjectID"] + ""); 57 ProjectCode = context.Request["ProjectCode"] + ""; 58 59 string excelName = postFile.FileName; 60 string savePath = ""; 61 62 try 63 { 64 65 /*文件是否有内容*/ 66 if (postFile != null && postFile.ContentLength > 0) 67 { 68 if (string.IsNullOrEmpty(excelName)) 69 { 70 excelName = Guid.NewGuid().ToString("N") + System.IO.Path.GetExtension(postFile.FileName); 71 } 72 73 if (!File.Exists(Path)) 74 { 75 System.IO.Directory.CreateDirectory(Path); 76 } 77 78 string Mess = ""; 79 savePath = Path + excelName; 80 postFile.SaveAs(savePath); 81 82 if (Mess != "") 83 { 84 //错误输出 85 context.Response.Write("false@" + Mess); 86 } 87 88 Mess = DealExcelForHangQiLun(LoadDataFromExcel(savePath)); 89 if (string.IsNullOrEmpty(Mess)) 90 { 91 Mess = "导入成功!" + "@true"; 92 } 93 result = "true@" + Mess; 94 } 95 } 96 catch (Exception ex) 97 { 98 result = "false@上传失败!" + ex.ToString(); 99 } 100 context.Response.Write(result); 101 } 102 103 public static string DealExcelForHangQiLun(DataSet ds) 104 { 105 try 106 { 107 string errorRow = ""; 108 string repeatstr = ""; 109 int clevel = 0; 110 Dictionary<string, ExcelModel> goodsdictionary = new Dictionary<string, ExcelModel>(); 111 112 if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) 113 { 114 //获取Excel 最大层级并分级 115 Dictionary<int, List<ExcelModel>> dictionary = GetExcelDataByClevel(ds, out clevel, out errorRow, out repeatstr, out goodsdictionary); 116 117 if (string.IsNullOrEmpty(errorRow) && string.IsNullOrEmpty(repeatstr)) 118 { 119 if (clevel > 0) 120 { 121 //根据项目编号删除BOM 122 new Md.HangQiLun().DeleteListByColunm("ProjectID", ProjectID.ToString()); 123 //根据项目编号删除物号信息表(HasProjectCode=0) 124 new Md.HangQiLun().DeleteGoodsList(ProjectID, CompID); 125 //批量存储物号信息 126 Dictionary<string, int> goodsdic = SaveGoodsInfo(goodsdictionary); 127 //keeplist = new List<List<Hashtable>>(); 128 if (dictionary.Count > 0) 129 { 130 RecursiveSave(dictionary, goodsdic); 131 } 132 } 133 } 134 else 135 { 136 137 //排除自身重复的数字 138 if (!string.IsNullOrEmpty(errorRow)) 139 { 140 string errorstr = DeduplicationData(errorRow.TrimEnd(',')); 141 errorRow = "此Excel表格中," + "第 " + errorstr + " 行的序号或者代号不能为空"; 142 } 143 if (!string.IsNullOrEmpty(errorRow) && !string.IsNullOrEmpty(repeatstr)) 144 { 145 errorRow += ",且"; 146 } 147 if (!string.IsNullOrEmpty(repeatstr)) 148 { 149 errorRow += "此Excel表格中," + repeatstr; 150 } 151 errorRow += ",请检查修正后,重新导入!@false"; 152 } 153 } 154 else 155 { 156 errorRow = "此Excel表格没有任何数据!" + "@false"; 157 } 158 return errorRow; 159 } 160 catch (Exception ex) 161 { 162 return null; 163 } 164 } 165 166 /// <summary> 167 /// 处理重复的数据,返回错误行数 168 /// </summary> 169 /// <param name="errorRow">excel表格</param>. 170 private static string DeduplicationData(string errorRow) 171 { 172 //1.把字符串转换成数组 173 string[] str = errorRow.Split(','); 174 175 //2.定义ArrayList,判断数组中重复字段不添加到 ArrayList对象中 176 ArrayList array = new ArrayList(); 177 for (int i = 0; i < str.Length; i++) 178 { 179 //判断是否已经存在 180 if (array.Contains(str[i]) == false) 181 { 182 array.Add(str[i]); 183 } 184 } 185 186 //3.将arrayList转换成数组 187 str = new string[array.Count]; 188 str = (string[])array.ToArray(typeof(string)); 189 190 //4.字节数组转换成字符串 191 string mess = ""; 192 for (int i = 0; i < str.Length; i++) 193 { 194 mess += str[i] + ","; 195 } 196 197 return mess.TrimEnd(','); 198 } 199 200 /// <summary> 201 /// 根据层级将Excel表的分级处理 202 /// </summary> 203 /// <param name="ds">excel表格</param>. 204 /// <param name="clevel">层级</param> 205 /// <param name="errorRow">序号/代号不能为空</param> 206 /// <param name="repeatstr">不能有重复的序号</param> 207 /// <param name="goodsdictionary">物号集合</param> 208 private static Dictionary<int, List<ExcelModel>> GetExcelDataByClevel(DataSet ds, out int clevel, out string errorRow, out string repeatstr, out Dictionary<string, ExcelModel> goodsdictionary) 209 { 210 #region 定义变量 211 errorRow = ""; 212 repeatstr = ""; 213 clevel = 0; 214 string str = string.Empty; 215 ArrayList array = new ArrayList(); 216 goodsdictionary = new Dictionary<string, ExcelModel>(); 217 Dictionary<int, List<ExcelModel>> dictionary = new Dictionary<int, List<ExcelModel>>(); 218 int dsRows = ds.Tables[0].Rows.Count; 219 #endregion 220 221 for (int i = 0; i < dsRows; i++) 222 { 223 #region model赋值 224 DataRow item = ds.Tables[0].Rows[i]; 225 string cols1 = item[0].ToString(); 226 string cols2 = item[1].ToString(); 227 ExcelModel excelmodel = new ExcelModel(); 228 excelmodel.No = cols1; 229 excelmodel.GNumCode = cols2; 230 excelmodel.GnumName = item[2].ToString(); 231 excelmodel.DocNo = item[3].ToString(); 232 excelmodel.Num = Convert.ToInt32(item[4].ToString()); 233 excelmodel.Stuff = item[5].ToString(); 234 excelmodel.Weight = Convert.ToDouble(item[6]); 235 excelmodel.AllWeight = Convert.ToDouble(item[7]); 236 excelmodel.Level = item[0].ToString().Split('.').Length; 237 #endregion 238 239 #region 数据处理 240 //遍历excel 序号和代号,不能为空 241 if (string.IsNullOrEmpty(cols1) || string.IsNullOrEmpty(cols2)) 242 { 243 errorRow += (i + 3) + ","; 244 } 245 //遍历excel 序号不能有重复的 246 if (array.Contains(cols1) == false) 247 { 248 array.Add(cols1); 249 } 250 //获取最大层级 251 if (str.Length < item[0].ToString().Length) 252 { 253 str = item[0].ToString(); 254 } 255 #endregion 256 257 #region 物号(代号)数据处理 258 if (goodsdictionary.Keys.Contains(cols2) == false) 259 { 260 goodsdictionary.Add(cols2, excelmodel); 261 } 262 #endregion 263 264 #region 数据分级处理 265 List<ExcelModel> listModel = new List<ExcelModel>(); 266 if (dictionary.Keys.Contains(excelmodel.Level) == false) 267 { 268 listModel.Add(excelmodel); 269 dictionary.Add(excelmodel.Level, listModel); 270 } 271 else 272 { 273 listModel = dictionary[excelmodel.Level]; 274 listModel.Add(excelmodel); 275 } 276 #endregion 277 } 278 #region 返回值 279 if (dsRows != array.Count) 280 { 281 repeatstr = "存在重复的序号"; 282 } 283 if (!string.IsNullOrEmpty(str)) 284 { 285 clevel = str.Split('.').Length; 286 } 287 return dictionary; 288 #endregion 289 } 290 291 /// <summary> 292 /// 保存并获取物号信息 293 /// </summary> 294 /// <param name="goodsdictionary"></param> 295 /// <returns></returns> 296 private static Dictionary<string, int> SaveGoodsInfo(Dictionary<string, ExcelModel> goodsdictionary) 297 { 298 Dictionary<string, int> goodsdic = new Dictionary<string, int>(); 299 StringBuilder sql = new StringBuilder(); 300 foreach (var item in goodsdictionary) 301 { 302 ExcelModel model = item.Value; 303 string projectcode = model.GNumCode.Substring(0, model.GNumCode.IndexOf("-"));//项目编号 304 string hasprojectcode = ""; 305 if (ProjectCode == projectcode) 306 { 307 hasprojectcode = "0";//物号中是否拼接项目编号 0 拼接 308 } 309 else 310 { 311 hasprojectcode = "1";//物号中是否拼接项目编号 1不拼接 312 } 313 int isexist = 0; 314 if (hasprojectcode == "1") 315 { 316 //查询该不拼接的物号是否已存在数据库中 317 isexist = new Md.HangQiLun().GetGoodsList(CompID, model.GNumCode); 318 } 319 if (isexist > 0) 320 { 321 if (goodsdic.Keys.Contains(model.GNumCode) == false) 322 { 323 goodsdic.Add(model.GNumCode, isexist); 324 } 325 } 326 else 327 { 328 sql.Append("('" + model.GnumName + "', '" + model.GNumCode + "', " + ProjectID + ", '" + hasprojectcode + "', " + CompID + "),"); 329 } 330 } 331 //存入库 -取数据 332 if (sql.Length > 0) 333 { 334 sql.Remove(sql.Length - 1, 1); 335 DataSet ds = new Md.HangQiLun().BatchSave(sql.ToString(), CompID, ProjectID); 336 if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) 337 { 338 for (int j = 0; j < ds.Tables[0].Rows.Count; j++) 339 { 340 DataRow drRows = ds.Tables[0].Rows[j]; 341 string gnumcode = drRows["GNumCode"].ToString(); 342 int gnumid = Convert.ToInt32(drRows["ID"].ToString()); 343 if (goodsdic.Keys.Contains(gnumcode) == false) 344 { 345 goodsdic.Add(gnumcode, gnumid); 346 } 347 } 348 } 349 } 350 return goodsdic; 351 } 352 353 354 /// <summary> 355 /// 递归遍历 356 /// </summary> 357 /// <param name="ds">excel表格</param>. 358 /// <param name="Tlist">父级集合</param> 359 /// <param name="clevel">层级</param> 360 /// <param name="x">从第几个循环</param> 361 /// 362 public static void RecursiveSave(Dictionary<int, List<ExcelModel>> dictionary, Dictionary<string, int> goodsdic, int level = 1, List<Hashtable> Tlist = null, int SortID = 999) 363 { 364 try 365 { 366 if (dictionary.Keys.Contains(level)) 367 { 368 if (level == 1) 369 { 370 int sorid = 999; 371 List<Hashtable> list = SaveHangQiLun(dictionary[1], goodsdic, out sorid); 372 RecursiveSave(dictionary, goodsdic, 2, list, sorid); 373 } 374 else 375 { 376 int sorid = 999; 377 List<Hashtable> list = SaveHangQiLun(dictionary[level], goodsdic, out sorid, Tlist); 378 level++; 379 RecursiveSave(dictionary, goodsdic, level, list); 380 } 381 } 382 } 383 catch (Exception ex) 384 { 385 throw ex; 386 } 387 } 388 389 390 /// <summary> 391 /// 保存同级别的数据 392 /// </summary> 393 /// <param name="dictionary"></param> 394 /// <param name="goodsdic">物号信息</param> 395 /// <param name="sorid">返回排序数</param> 396 /// <param name="Plist">父级</param> 397 /// <param name="SortID">排序数</param> 398 /// <returns></returns> 399 private static List<Hashtable> SaveHangQiLun(List<ExcelModel> dictionary, Dictionary<string, int> goodsdic, out int sorid, List<Hashtable> Plist=null, int SortID = 999) 400 { 401 List<Hashtable> Tlist = new List<Hashtable>(); 402 StringBuilder sql = new StringBuilder(); 403 404 for (int i = 0; i < dictionary.Count; i++) 405 { 406 ExcelModel model = dictionary[i]; 407 408 #region 保存BOM表 409 int goodsID = 0; 410 if (goodsdic.Keys.Contains(model.GNumCode) == true) 411 { 412 goodsID = goodsdic[model.GNumCode]; 413 } 414 415 if (Plist == null) 416 { 417 model.PID = 0; 418 } 419 else 420 { 421 string pidstr = model.No.Substring(0, model.No.LastIndexOf('.')); 422 Hashtable table = 423 Plist.Where(p => p["oldNO"].ToString() == pidstr).First(); 424 int pid = Convert.ToInt32(table["BOMID"] + ""); 425 model.PID = pid; 426 } 427 SortID++; 428 sql.Append("(" + model.PID + "," + model.Num + "," + goodsID + ",'" + model.Stuff + "'," + model.Weight + "," + model.AllWeight + "," + CreateUser + ",'" + DateTime.Now + "'," + ProjectID + ",'0'," + SortID + ",'" + model.No + "'," + CompID + "),"); 429 #endregion 430 } 431 sorid = SortID; 432 //存入le_bom表,并取数据 433 sql.Remove(sql.Length - 1, 1); 434 DataSet ds = new Md.HangQiLun().BatchSaveBom(sql.ToString(), CompID, ProjectID); 435 if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) 436 { 437 for (int j = 0; j < ds.Tables[0].Rows.Count; j++) 438 { 439 DataRow drRows = ds.Tables[0].Rows[j]; 440 #region 存入集合 441 Hashtable table = new Hashtable(); 442 table.Add("BOMID", drRows["ID"]); 443 table.Add("oldNO", drRows["OldID"]); 444 Tlist.Add(table); 445 #endregion 446 } 447 } 448 return Tlist; 449 } 450 451 452 /// <summary> 453 /// Excel解读至DataSet 454 /// </summary> 455 /// <param name="filePath"></param> 456 /// <returns></returns> 457 public static DataSet LoadDataFromExcel(string filePath) 458 { 459 try 460 { 461 string strConn; 462 strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + 463 ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1;'"; 464 OleDbConnection OleConn = new OleDbConnection(strConn); 465 OleConn.Open(); 466 467 string tbName = OleConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null).Rows[0][2].ToString().Trim(); 468 String sql = "SELECT * FROM [" + tbName + "A2:H65535" + "]"; //可是更改Sheet名称,比如sheet2,等等 469 OleDbDataAdapter OleDaExcel = new OleDbDataAdapter(sql, OleConn); 470 DataSet OleDsExcle = new DataSet(); 471 OleDaExcel.Fill(OleDsExcle, tbName); 472 OleConn.Close(); 473 return OleDsExcle; 474 } 475 catch (Exception ex) 476 { 477 return null; //"数据绑定Excel失败!失败原因:" + err.Message + "提示信息"; 478 } 479 } 480 481 /// <summary> 482 /// 定义class 类 483 /// </summary> 484 /// <returns></returns> 485 public class ExcelModel 486 { 487 /// <summary> 488 /// 序号 489 /// </summary> 490 public string No { get; set; } 491 /// <summary> 492 /// 物号编号 493 /// </summary> 494 public string GNumCode { get; set; } 495 /// <summary> 496 /// 物号名称 497 /// </summary> 498 public string GnumName { get; set; } 499 /// <summary> 500 /// 资料号 501 /// </summary> 502 public string DocNo { get; set; } 503 /// <summary> 504 /// 物号数量 505 /// </summary> 506 public int Num { get; set; } 507 /// <summary> 508 /// 材料 509 /// </summary> 510 public string Stuff { get; set; } 511 /// <summary> 512 /// 单物重量 513 /// </summary> 514 public Double Weight { get; set; } 515 /// <summary> 516 /// 总重量 517 /// </summary> 518 public Double AllWeight { get; set; } 519 /// <summary> 520 /// 层级 521 /// </summary> 522 public int Level { get; set; } 523 /// <summary> 524 /// 父级ID 525 /// </summary> 526 public int PID { get; set; } 527 } 528 public bool IsReusable 529 { 530 get 531 { 532 return false; 533 } 534 } 535 } 536 }

浙公网安备 33010602011771号