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 }

 

posted @ 2016-08-09 10:08  指尖的人生  阅读(3310)  评论(0)    收藏  举报