Преглед изворни кода

优化导出生成模块代码

zhangjiaxin пре 4 недеља
родитељ
комит
a9c08caad6

+ 474 - 457
OTSIncAReportApp/1-UI/OTSReportExport/DataIntegration/BasicData.cs

@@ -1,5 +1,4 @@
-
-using DevExpress.Office.Drawing;
+using DevExpress.Office.Drawing;
 using NPOI.Util;
 using OTSCommon.DBOperate;
 using OTSIncAReportApp.DataOperation.DataAccess;
@@ -35,116 +34,80 @@ namespace OTSIncAReportApp._1_UI.OTSReportExport.DataIntegration
         private string FilePath = "";
 
         private string VDA19String = "5,15,25,50,100,150,200,400,600,1000";
+
         /// <summary>
         /// 获取粒级表
         /// </summary>
         public void SetParticlesizeTable(OTSReport_Export m_otsreport_export)
         {
+            colid.Clear();
             colid_Below7.Clear();
-            //获取粒级表
+
             string path1 = m_otsreport_export.m_ReportApp.m_rstDataMgr.m_RptConfigFile.PartSizeFileFolder +
                  m_otsreport_export.m_ReportApp.m_rstDataMgr.m_RptConfigFile.PartSizeFile;
             DataSet ds = OTSIncAReportApp.DataOperation.DataAccess.XMLoperate.GetXml(path1);
             SizeChart = ds.Tables[0].Rows[0]["Sizes"].ToString();
 
-            for (int i = 0; i < SizeChart.Split(',').Length; i++)
-            {
-                if (SizeChart.Split(',')[i].Length > 0)
-                {
-                    double d1 = Convert.ToDouble(SizeChart.Split(',')[i]);
-                    //double d2 = Convert.ToDouble(SizeChart.Split(',')[i + 1]);
-                    colid.Add("≥"+ d1.ToString() /*+ "~" + d2.ToString()*/);
-                }
-            }
-
-
-            for (int i = 0; i < SizeChart.Split(',').Length - 1; i++)
-            {
-                if (SizeChart.Split(',')[i].Length > 0)
-                {
-                    double d1 = Convert.ToDouble(SizeChart.Split(',')[i]);
-                    double d2 = Convert.ToDouble(SizeChart.Split(',')[i + 1]);
-                    colid_Below7.Add(d1.ToString() + "~" + d2.ToString());
-                } 
-            }
-            double d = Convert.ToDouble(SizeChart.Split(',')[SizeChart.Split(',').Length - 1]);
-            colid_Below7.Add(d.ToString() + "~MAX");
-            //double d = Convert.ToDouble(SizeChart.Split(',')[SizeChart.Split(',').Length - 1]);
-            //colid.Add(d.ToString() + "~MAX");
+            var sizes = ParseSizeString(SizeChart);
+            BuildSizeColumnLists(sizes, colid, colid_Below7);
         }
+
         /// <summary>
         /// 获取粒级表
         /// </summary>
         /// <returns></returns>
         public List<string> GetParticlesizeTable()
         {
-            if(colid.Count>7)
+            if (colid.Count > 7)
             {
                 return colid;
-            }else
+            }
+            else
             {
                 return colid_Below7;
             }
-            
+
         }
+
        
         public void SetDBData(c_TemplateClass m_mbszclass, OTSReport_Export m_otsreport_export, string ComputeMode)
         {
-            DataTable m_bt_DBData = new DataTable();
-            ParticleData fielddata = new ParticleData(m_otsreport_export.m_ReportApp.m_rstDataMgr.ResultFilesList[m_otsreport_export.m_ReportApp.m_rstDataMgr.GetWorkingResultId()].FilePath);
-            List<string> colid = new List<string>() { "TypeName", "ar", "TypeId", "Largest", "Class", "GroupId", "con" };
-            //获取粒级表
+            // 输出集合初始化
+            BData = new List<DataTable>();
+            Measurements = new List<DataTable>();
+
+            // 本次使用的 ParticleData(局部)
+            ParticleData particleData = new ParticleData(m_otsreport_export.m_ReportApp.m_rstDataMgr.ResultFilesList[m_otsreport_export.m_ReportApp.m_rstDataMgr.GetWorkingResultId()].FilePath);
+
+            // 基础列
+            var baseCols = new List<string> { "TypeName", "ar", "TypeId", "Largest", "Class", "GroupId", "con" };
+
+            // 获取粒级表 sizestr(支持 VDA19)
             string path1 = m_otsreport_export.m_ReportApp.m_rstDataMgr.m_RptConfigFile.PartSizeFileFolder +
                  m_otsreport_export.m_ReportApp.m_rstDataMgr.m_RptConfigFile.PartSizeFile;
             DataSet ds = OTSIncAReportApp.DataOperation.DataAccess.XMLoperate.GetXml(path1);
 
-            string sizestr = "";
-
-            if (m_mbszclass.M_VDA19.IsVDA19)
-                sizestr = VDA19String;
-            else
-                sizestr = ds.Tables[0].Rows[0]["Sizes"].ToString();
-
-            bool blBelow7 = false;
+            string sizestr = m_mbszclass.M_VDA19.IsVDA19 ? VDA19String : ds.Tables[0].Rows[0]["Sizes"].ToString();
+            var sizes = ParseSizeString(sizestr);
 
-            if (sizestr.Split(',').Length>7)
-            {
-                for (int i = 0; i < sizestr.Split(',').Length; i++)
-                {
-                    if (sizestr.Split(',')[i].Length > 0)
-                    {
-                        double d1 = Convert.ToDouble(sizestr.Split(',')[i]);
-                        //double d2 = Convert.ToDouble(sizestr.Split(',')[i + 1]);
-                        colid.Add("≥" + d1.ToString() /*+ "~" + d2.ToString()*/);
-                    }
-                }
-                blBelow7 = true;
-            }
-            else
-            {
-                for (int i = 0; i < sizestr.Split(',').Length - 1; i++)
-                {
-                    if (sizestr.Split(',')[i].Length > 0)
-                    {
-                        double d1 = Convert.ToDouble(sizestr.Split(',')[i]);
-                        double d2 = Convert.ToDouble(sizestr.Split(',')[i + 1]);
-                        colid.Add(d1.ToString() + "~" + d2.ToString());
-                    }
-                }
-                double d = Convert.ToDouble(sizestr.Split(',')[sizestr.Split(',').Length - 1]);
-                colid.Add(d.ToString() + "~MAX");
-                blBelow7 = false;
-            }
+            // 构建 size 列名(保留原有逻辑)
+            bool blBelow7;
+            List<string> sizeBucketNames;
+            BuildSizeColumns(sizes, out sizeBucketNames, out blBelow7);
 
-            for (int i = 0; i < colid.Count; i++)
+            // 构建 m_bt_DBData 列
+            DataTable m_bt_DBData = new DataTable();
+            foreach (var c in baseCols.Concat(sizeBucketNames))
             {
-                m_bt_DBData.Columns.Add(colid[i].ToString());
+                m_bt_DBData.Columns.Add(c);
             }
 
-            DataTable dt = InvalidRemoval(fielddata.GetParticleListForParticlSize("area", ""));
-            DataTable AreaInformationOfAllElements = InvalidRemoval(fielddata.GetAreaByAllIncA(""));
-            DataTable dtp = InvalidRemoval(fielddata.GetParticleAll(""));
+            // 读取并过滤原始数据(TypeId > 10)
+            DataTable dt = InvalidRemoval(particleData.GetParticleListForParticlSize("area", ""));
+            DataTable AreaInformationOfAllElements = InvalidRemoval(particleData.GetAreaByAllIncA(""));
+            DataTable dtp = InvalidRemoval(particleData.GetParticleAll(""));
 
+            // 计算匹配列名 po
             string po = ComputeMode;
             switch (po)
             {
@@ -162,298 +125,157 @@ namespace OTSIncAReportApp._1_UI.OTSReportExport.DataIntegration
                     break;
             }
 
-     
-
-
+            // 将 dtp 按 TypeId 建索引,避免多次 Select
+            var dtpByType = GroupRowsByType(dtp);
 
-			for (int i = 0; i < dt.Rows.Count; i++)
+            // 构建 m_bt_DBData 行
+            foreach (DataRow srcRow in dt.Rows)
             {
+                string typeId = srcRow["TypeId"].ToString();
                 DataRow dr = m_bt_DBData.NewRow();
-                dr["TypeName"] = dt.Rows[i]["TypeName"].ToString();
-                dr["TypeId"] = dt.Rows[i]["TypeId"].ToString();
-                dr["con"] = dt.Rows[i]["con"].ToString();
-
-                dr["GroupId"] = dt.Rows[i]["GroupId"].ToString();
-				if (dt.Rows[i]["GroupName"].ToString() == "")
-                    dr["Class"] = "Default";
-                else
-                    dr["Class"] = dt.Rows[i]["GroupName"].ToString();
-                //continue;
-                dr["Largest"] = Math.Round(Convert.ToDouble(dt.Rows[i]["max"]), 2);
-
-                if(blBelow7)
+                dr["TypeName"] = srcRow["TypeName"].ToString();
+                dr["TypeId"] = typeId;
+                dr["con"] = srcRow["con"].ToString();
+                dr["GroupId"] = srcRow["GroupId"].ToString();
+                dr["Class"] = string.IsNullOrEmpty(srcRow["GroupName"].ToString()) ? "Default" : srcRow["GroupName"].ToString();
+                dr["Largest"] = Math.Round(Convert.ToDouble(srcRow["max"]), 2);
+
+                List<DataRow> rowsOfType;
+                dtpByType.TryGetValue(typeId, out rowsOfType);
+                if (rowsOfType == null) rowsOfType = new List<DataRow>();
+
+                // 为每个 size bucket 计数
+                for (int a = 0; a < sizeBucketNames.Count; a++)
                 {
-                    for (int a = 7; a < colid.Count; a++)
+                    double min = 0, max = double.MaxValue;
+                    if (blBelow7)
                     {
-                        string d1 = colid[a].Split('≥')[1];
-                        string d2;
-                        if (a == colid.Count - 1)
-                        {
-                            d2 = "9999999999999";
-                        }
-                        else
-                        {
-                            d2 = colid[a + 1].Split('≥')[1];
-                        }
-                        DataRow[] datas = dtp.Select(getWhere(d2, d1, po, dt.Rows[i]["TypeId"].ToString()));
-                        dr[colid[a]] = datas.Count();
+                        min = sizes[a];
+                        max = (a < sizes.Count - 1) ? sizes[a + 1] : double.MaxValue;
                     }
-                }
-                else
-                {
-                    for (int a = 7; a < colid.Count; a++)
+                    else
                     {
-                        string d1 = colid[a].Split('~')[0];
-                        string d2 = colid[a].Split('~')[1];
-                        if (d2 == "MAX")
+                        var parts = sizeBucketNames[a].Split('~');
+                        double.TryParse(parts[0], out min);
+                        if (parts.Length > 1 && parts[1] != "MAX")
+                        {
+                            double.TryParse(parts[1], out max);
+                        }
+                        else if (parts.Length > 1 && parts[1] == "MAX")
                         {
-                            d2 = "999";
+                            max = double.MaxValue;
                         }
-                        DataRow[] datas = dtp.Select(getWhere(d2, d1, po, dt.Rows[i]["TypeId"].ToString()));
-                        dr[colid[a]] = datas.Count();
                     }
+
+                    int count = CountRowsInRange(rowsOfType, po, min, max);
+                    dr[sizeBucketNames[a]] = count;
                 }
-             
-                for (int a = 0; a < AreaInformationOfAllElements.Rows.Count; a++)
+
+                // ar 字段填充
+                dr["ar"] = 0;
+                foreach (DataRow arRow in AreaInformationOfAllElements.Rows)
                 {
-                    if (dt.Rows[i]["TypeId"].ToString() == AreaInformationOfAllElements.Rows[a]["TypeId"].ToString())
+                    if (arRow["TypeId"].ToString() == typeId)
                     {
-                        dr["ar"] = AreaInformationOfAllElements.Rows[a]["ar"];
+                        dr["ar"] = arRow["ar"];
+                        break;
                     }
                 }
+
                 m_bt_DBData.Rows.Add(dr);
             }
 
+            // 按名称过滤不需要的物质分类(保持原行为)
+            FilterByDeleteClass(m_bt_DBData, m_mbszclass);
 
+			// 构建 GroupInformation(去重)
+			GroupInformation = ExtractUniqueClasses(m_bt_DBData, "Class");
+			//GroupInformation = m_bt_DBData.AsEnumerable()
+   //                                      .Select(r => r["Class"].ToString())
+   //                                      .Distinct()
+   //                                      .ToList();
 
-            //去除物质分类(非夹杂物分类)//颗粒种类ID赛选
-            //for (int a = 0; a < m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass_Serial.Count; a++)
-            //{
-            //    for (int i = m_bt_DBData.Rows.Count - 1; i >= 0; i--)
-            //    {
-            //        if (m_bt_DBData.Rows[i]["TypeId"].ToString() == m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass_Serial[a].ToString())
-            //        {
-            //            m_bt_DBData.Rows.RemoveAt(i);
-            //        }
-            //    }
-            //}
-
-			//去除物质分类(非夹杂物分类)//颗粒种类名称赛选
-			for (int a = 0; a < m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass.Count; a++)
-			{
-				for (int i = m_bt_DBData.Rows.Count - 1; i >= 0; i--)
-				{
-					if (m_bt_DBData.Rows[i]["TypeName"].ToString() == m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass[a].ToString())
-					{
-						m_bt_DBData.Rows.RemoveAt(i);
-					}
-				}
-			}
-
-			GroupInformation = new List<string>();
-			for (int i = 0; i < m_bt_DBData.Rows.Count; i++)
-			{
-				bool bl = false;
-				for (int a = 0; a < GroupInformation.Count; a++)
-                {
-					if (GroupInformation[a] == m_bt_DBData.Rows[i]["Class"].ToString())
-					{
-						bl = true;
-					}
-				}
-				if (!bl)
-				{
-					GroupInformation.Add(m_bt_DBData.Rows[i]["Class"].ToString());
-				}
-			}
-            
+            // 系统类型为 IncA 时,按 Class 拆分
             if (m_otsreport_export.m_ReportApp.m_RptConfigFile.Systype == OTS_SysType_ID.IncA)
             {
-                Measurements = new List<DataTable>();
-
-				for (int i = 0; i < GroupInformation.Count; i++)
+                BData = GroupInformation.Select(g =>
                 {
-                    DataTable table = m_bt_DBData.Clone();
-                    for (int a = 0; a < m_bt_DBData.Rows.Count; a++)
+                    var t = m_bt_DBData.Clone();
+                    foreach (DataRow r in m_bt_DBData.Rows)
                     {
-                        if (GroupInformation[i] == m_bt_DBData.Rows[a]["Class"].ToString())
-                        {
-                            table.Rows.Add(m_bt_DBData.Rows[a].ItemArray);
-						}
+                        if (r["Class"].ToString() == g) t.Rows.Add(r.ItemArray);
                     }
-                    BData.Add(table);
-				}
-                //Measurements = BData.Copy();
+                    return t;
+                }).ToList();
 
-				for (int i = 0; i < GroupInformation.Count; i++)
-				{
-					DataTable table = dtp.Clone();
-					for (int a = 0; a < dtp.Rows.Count; a++)
-					{
-						if (GroupInformation[i] == dtp.Rows[a]["GroupName"].ToString())
-						{
-							table.Rows.Add(dtp.Rows[a].ItemArray);
-						}
-					}
-					Measurements.Add(table);
-				}
-				return;
+                Measurements = GroupInformation.Select(g =>
+                {
+                    var t = dtp.Clone();
+                    foreach (DataRow r in dtp.Rows)
+                    {
+                        string groupName = string.IsNullOrEmpty(r["GroupName"].ToString()) ? "Default" : r["GroupName"].ToString();
+                        if (groupName == g) t.Rows.Add(r.ItemArray);
+                    }
+                    return t;
+                }).ToList();
 
+                return;
+            }
 
-			}
+			// 判断是否使用指定组(RuleGroup 中存在 GroupId == "0")
+			bool useSpecifyGroups = TableContainsGroupIdZero(m_otsreport_export.m_mbszclass.RuleGroup);
 
-				#region 判断是否使用指定选择组和规则
-				bool bl1 = false;
-			for (int i = 0; i < m_otsreport_export.m_mbszclass.RuleGroup.Rows.Count; i++)
-			{
-				if (m_otsreport_export.m_mbszclass.RuleGroup.Rows[i]["GroupId"].ToString() == "0")
-				{
-					bl1 = true;
-				}
-			}
-			#endregion
+			//bool useSpecifyGroups = m_otsreport_export.m_mbszclass.RuleGroup.AsEnumerable()
+   //                                     .Any(r => r["GroupId"].ToString() == "0");
 
-			if (!bl1)
+            if (!useSpecifyGroups)
             {
-				#region 筛选现有组
-				List<string> strings = new List<string>();
-				for (int i = 0; i < m_bt_DBData.Rows.Count; i++)
-				{
-					bool bl2 = false;
-					for (int a = 0; a < strings.Count; a++)
-					{
-						if (m_bt_DBData.Rows[i]["GroupId"].ToString() == strings[a])
-						{
-							bl2 = true;
-						}
-					}
-					if (!bl2)
-					{
-						strings.Add(m_bt_DBData.Rows[i]["GroupId"].ToString());
-					}
-				}
-				#endregion
-
-
-				List<DataTable> OutData = new List<DataTable>();
-
-                for (int i = 0; i < strings.Count(); i++)
+				// 按现有 GroupId 拆分 BData
+				var groups = ExtractUniqueClasses(m_bt_DBData, "GroupId");
+				//var groups = m_bt_DBData.AsEnumerable()
+    //                                    .Select(r => r["GroupId"].ToString())
+    //                                    .Distinct()
+    //                                    .ToList();
+
+                BData = groups.Select(g =>
                 {
-					DataTable data = m_bt_DBData.Clone();
-					for (int a = 0; a < m_bt_DBData.Rows.Count; a++)
+                    var t = m_bt_DBData.Clone();
+                    foreach (DataRow r in m_bt_DBData.Rows)
                     {
-                        if (strings[i] == m_bt_DBData.Rows[a]["GroupId"].ToString())
-                        {
-                            data.Rows.Add(m_bt_DBData.Rows[a].ItemArray);
-						}
+                        if (r["GroupId"].ToString() == g) t.Rows.Add(r.ItemArray);
                     }
-                    OutData.Add(data);
-				}
-
-                BData = OutData.Copy();
-				Measurements = new List<DataTable>();
-
-				for (int i = 0; i < GroupInformation.Count; i++)
-				{
-					DataTable table = dtp.Clone();
-					for (int a = 0; a < dtp.Rows.Count; a++)
-					{
-                        string strGroupId = "Default";
-						if (dtp.Rows[a]["GroupName"].ToString() != "") 
-                        {
-                            strGroupId = dtp.Rows[a]["GroupName"].ToString();
-						}
-						if (GroupInformation[i] == strGroupId)
-						{
-							table.Rows.Add(dtp.Rows[a].ItemArray);
-						}
-					}
-					Measurements.Add(table);
-				}
-				return;
-			}
-
-            List<DataTable> SpecifyGroup = new List<DataTable>();
-			for (int i = 0; i < m_otsreport_export.m_mbszclass.List_data.Count; i++)
-            {
-				DataTable data= m_bt_DBData.Clone();
+                    return t;
+                }).ToList();
 
-                bool b3 = false;
-                string str_class = "";
-                for (int a = 0; a < m_otsreport_export.m_mbszclass.RuleGroup.Rows.Count; a++)
+                // Measurements 按 GroupInformation 拆分
+                Measurements = GroupInformation.Select(g =>
                 {
-                    if (m_otsreport_export.m_mbszclass.RuleGroup.Rows[a]["GroupId"].ToString() == m_otsreport_export.m_mbszclass.List_data[i].TableName)
+                    var t = dtp.Clone();
+                    foreach (DataRow r in dtp.Rows)
                     {
-                        if (m_otsreport_export.m_mbszclass.RuleGroup.Rows[a]["display"].ToString() == "1")
-                        {
-                            str_class = m_otsreport_export.m_mbszclass.RuleGroup.Rows[a]["GroupName"].ToString();
-							b3 = true;
-						}
-					}
-                }
-				data.TableName = m_otsreport_export.m_mbszclass.List_data[i].TableName;
-				if (b3)
-                {
-					for (int a = 0; a < m_otsreport_export.m_mbszclass.List_data[i].Rows.Count; a++)
-					{
-						if (m_otsreport_export.m_mbszclass.List_data[i].Rows[a]["display"].ToString() == "1")
-						{
-							DataTable data1 = m_bt_DBData.Clone();
-							DataRow row = data.NewRow();
-							row["TypeName"] = m_otsreport_export.m_mbszclass.List_data[i].Rows[a]["StrName"];
-							row["ar"] = 0;
-							row["TypeId"] = m_otsreport_export.m_mbszclass.List_data[i].Rows[a]["STDId"];
-							row["GroupId"] = m_otsreport_export.m_mbszclass.List_data[i].Rows[a]["GroupId"];
-							row["con"] = 0;
-                            row["Largest"] = 0;
-                            row["Class"] = str_class;
-                            for (int j = 7; j < data.Columns.Count; j++)
-                            {
-                                row[j] = 0;
-							}
-
-							bool b2 = false;
-							for (int j = 0; j < m_bt_DBData.Rows.Count; j++)
-							{
-								if (m_otsreport_export.m_mbszclass.List_data[i].Rows[a]["STDId"].ToString() == m_bt_DBData.Rows[j]["TypeId"].ToString())
-								{
-									data1.Rows.Add(m_bt_DBData.Rows[j].ItemArray);
-									b2 = true;
-								}
-							}
-							if (b2)
-							{
-								data.Rows.Add(data1.Rows[0].ItemArray);
-							}
-							else
-							{
-								data.Rows.Add(row);
-							}
-						}
-					}
-				}
-				SpecifyGroup.Add(data);
-			}
-
-            BData = SpecifyGroup.Copy();
+                        string strGroupId = string.IsNullOrEmpty(r["GroupName"].ToString()) ? "Default" : r["GroupName"].ToString();
+                        if (strGroupId == g) t.Rows.Add(r.ItemArray);
+                    }
+                    return t;
+                }).ToList();
 
+                return;
+            }
 
+            // 使用指定规则组:按模板 m_mbszclass.List_data 构造
+            BData = BuildSpecifyGroup(m_bt_DBData, m_mbszclass);
 
-            #region 测量结果颗粒组队列
+            // 测量结果颗粒组队列(修复原代码索引误用)
             List<DataTable> datas1 = new List<DataTable>();
-			List<string> stringsa = fielddata.ObtainParticleCategory(m_otsreport_export, this);
+			List<string> stringsa = particleData.ObtainParticleCategory(m_otsreport_export, this);
 			for (int i = 0; i < stringsa.Count; i++)
 			{
 				DataTable data = dtp.Clone();
 				for (int a = 0; a < dtp.Rows.Count; a++)
 				{
-					if (Convert.ToInt64(dtp.Rows[i]["TypeId"]) > 10)
-					{
-                        string strGroupName = "Default";
-                        if (dtp.Rows[a]["GroupName"].ToString() != "")
-                        {
-                            strGroupName = dtp.Rows[a]["GroupName"].ToString();
-						}
+                    if (Convert.ToInt64(dtp.Rows[i]["TypeId"]) > 10)
+                    {
+                        string strGroupName = string.IsNullOrEmpty(dtp.Rows[a]["GroupName"].ToString()) ? "Default" : dtp.Rows[a]["GroupName"].ToString();
 						if (stringsa[i].ToString() == strGroupName)
 						{
 							data.Rows.Add(dtp.Rows[a].ItemArray);
@@ -500,17 +322,215 @@ namespace OTSIncAReportApp._1_UI.OTSReportExport.DataIntegration
 					Measurements.Add(table);
 				}
 			}
-			#endregion
+        }
+
+		// ---------- 私有辅助函数 ----------
 
+		private bool TableContainsGroupIdZero(DataTable table)
+		{
+			if (table == null || table.Rows.Count == 0) return false;
+			foreach (DataRow row in table.Rows)
+			{
+				if (row == null) continue;
+				var obj = row["GroupId"];
+				if (obj == null) continue;
+				if (obj.ToString().Trim() == "0") return true;
+			}
+			return false;
 		}
-        /// <summary>
-        /// 获取夹杂物组信息
-        /// </summary>
-        /// <returns></returns>
+		private List<string> ExtractUniqueClasses(DataTable table ,string textNmae)
+		{
+			var set = new HashSet<string>();
+			if (table == null) return new List<string>();
 
-        public List<string> GetGroupInformation()
-        {
-            return GroupInformation;
+			foreach (DataRow row in table.Rows)
+			{
+				if (row == null) continue;
+				var obj = row[textNmae];
+				if (obj == null) continue;
+				var s = obj.ToString().Trim();
+				if (string.IsNullOrEmpty(s)) continue;
+				set.Add(s);
+			}
+
+			return new List<string>(set);
+		}
+		private List<double> ParseSizeString(string sizestr)
+		{
+			if (string.IsNullOrEmpty(sizestr)) return new List<double>();
+			return sizestr.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
+						  .Select(s => { double.TryParse(s.Trim(), out double v); return v; })
+						  .ToList();
+		}
+
+		private void BuildSizeColumnLists(List<double> sizes, List<string> out_geCols, List<string> out_rangeCols)
+		{
+			out_geCols.Clear();
+			out_rangeCols.Clear();
+			if (sizes == null || sizes.Count == 0) return;
+
+			foreach (var d in sizes) out_geCols.Add("≥" + d.ToString());
+
+			for (int i = 0; i < sizes.Count - 1; i++)
+			{
+				out_rangeCols.Add(sizes[i].ToString() + "~" + sizes[i + 1].ToString());
+			}
+			out_rangeCols.Add(sizes.Last().ToString() + "~MAX");
+		}
+
+		private void BuildSizeColumns(List<double> sizes, out List<string> sizeBucketNames, out bool blBelow7)
+		{
+			sizeBucketNames = new List<string>();
+			blBelow7 = (sizes != null && sizes.Count > 7);
+			if (sizes == null || sizes.Count == 0) return;
+
+			if (blBelow7)
+			{
+				foreach (var d in sizes) sizeBucketNames.Add("≥" + d.ToString());
+			}
+			else
+			{
+				for (int i = 0; i < sizes.Count - 1; i++)
+				{
+					sizeBucketNames.Add(sizes[i].ToString() + "~" + sizes[i + 1].ToString());
+				}
+				sizeBucketNames.Add(sizes.Last().ToString() + "~MAX");
+			}
+		}
+
+		private Dictionary<string, List<DataRow>> GroupRowsByType(DataTable dtp)
+		{
+			var dict = new Dictionary<string, List<DataRow>>();
+			if (dtp == null) return dict;
+			foreach (DataRow r in dtp.Rows)
+			{
+				string key = r["TypeId"].ToString();
+				if (!dict.ContainsKey(key)) dict[key] = new List<DataRow>();
+				dict[key].Add(r);
+			}
+			return dict;
+		}
+
+		private int CountRowsInRange(List<DataRow> rows, string columnName, double min, double max)
+		{
+			if (rows == null || rows.Count == 0) return 0;
+			int cnt = 0;
+			if (columnName == "Area")
+			{
+				double areaMin = (min / 2.0) * (min / 2.0) * Math.PI;
+				double areaMax = (max == double.MaxValue) ? double.MaxValue : (max / 2.0) * (max / 2.0) * Math.PI;
+				foreach (var r in rows)
+				{
+					if (double.TryParse(r["Area"].ToString(), out double v))
+					{
+						if (v >= areaMin && v < areaMax) cnt++;
+					}
+				}
+			}
+			else
+			{
+				foreach (var r in rows)
+				{
+					if (double.TryParse(r[columnName].ToString(), out double v))
+					{
+						if (v >= min && v < max) cnt++;
+					}
+				}
+			}
+			return cnt;
+		}
+
+		private void FilterByDeleteClass(DataTable table, c_TemplateClass m_mbszclass)
+		{
+			if (m_mbszclass?.M_KLLBXX?.list_str_kllb_DeleteClass == null || m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass.Count == 0) return;
+			var toRemove = new HashSet<string>(m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass);
+			for (int i = table.Rows.Count - 1; i >= 0; i--)
+			{
+				if (toRemove.Contains(table.Rows[i]["TypeName"].ToString()))
+				{
+					table.Rows.RemoveAt(i);
+				}
+			}
+		}
+
+		private List<DataTable> BuildSpecifyGroup(DataTable m_bt_DBData, c_TemplateClass m_mbszclass)
+		{
+			var SpecifyGroup = new List<DataTable>();
+			for (int i = 0; i < m_mbszclass.List_data.Count; i++)
+			{
+				DataTable tpl = m_mbszclass.List_data[i];
+				DataTable data = m_bt_DBData.Clone();
+				bool visible = false;
+				string str_class = "";
+
+				foreach (DataRow rg in m_mbszclass.RuleGroup.Rows)
+				{
+					if (rg["GroupId"].ToString() == tpl.TableName)
+					{
+						if (rg["display"].ToString() == "1")
+						{
+							visible = true;
+							str_class = rg["GroupName"].ToString();
+						}
+						break;
+					}
+				}
+
+				data.TableName = tpl.TableName;
+				if (!visible)
+				{
+					SpecifyGroup.Add(data);
+					continue;
+				}
+
+				for (int a = 0; a < tpl.Rows.Count; a++)
+				{
+					if (tpl.Rows[a]["display"].ToString() != "1") continue;
+
+					string stdId = tpl.Rows[a]["STDId"].ToString();
+					var found = FindRowByTypeId(m_bt_DBData, stdId);
+					if (found != null)
+					{
+						data.Rows.Add(found.ItemArray);
+					}
+					else
+					{
+						DataRow newRow = data.NewRow();
+						newRow["TypeName"] = tpl.Rows[a]["StrName"];
+						newRow["ar"] = 0;
+						newRow["TypeId"] = stdId;
+						newRow["GroupId"] = tpl.Rows[a]["GroupId"];
+						newRow["con"] = 0;
+						newRow["Largest"] = 0;
+						newRow["Class"] = str_class;
+						for (int j = 7; j < data.Columns.Count; j++) newRow[j] = 0;
+						data.Rows.Add(newRow);
+					}
+				}
+
+				SpecifyGroup.Add(data);
+			}
+			return SpecifyGroup;
+		}
+
+		private DataRow FindRowByTypeId(DataTable table, string typeId)
+		{
+			foreach (DataRow r in table.Rows)
+			{
+				if (r["TypeId"].ToString() == typeId) return r;
+			}
+			return null;
+		}
+
+		// ---------- 其余方法保持原样 ----------
+
+		/// <summary>
+		/// 获取夹杂物组信息
+		/// </summary>
+		/// <returns></returns>
+		public List<string> GetGroupInformation()
+		{
+			return GroupInformation;
 		}
 		/// <summary>
 		/// 获取读取数据库并过滤颗粒
@@ -525,28 +545,28 @@ namespace OTSIncAReportApp._1_UI.OTSReportExport.DataIntegration
 		/// </summary>
 		/// <returns></returns>
 		public List<DataTable> etDBData()
-        {
-            return BData;
-        }
-        public void SetAllClass()
-        {
-            AllClass = fielddata.GetAllClass();
-        }
-        /// <summary>
-        /// 获取全部大类
-        /// </summary>
-        /// <returns></returns>
-        public DataTable GetAllClass()
-        {
-            return AllClass;
-        }
-        /// <summary>
-        ///测量结果数据列队
-        /// </summary>
-        /// <returns></returns>
-        public List<DataTable> GetMeasurements()
-        {
-            return Measurements;
+		{
+			return BData;
+		}
+		public void SetAllClass()
+		{
+			AllClass = fielddata.GetAllClass();
+		}
+		/// <summary>
+		/// 获取全部大类
+		/// </summary>
+		/// <returns></returns>
+		public DataTable GetAllClass()
+		{
+			return AllClass;
+		}
+		/// <summary>
+		///测量结果数据列队
+		/// </summary>
+		/// <returns></returns>
+		public List<DataTable> GetMeasurements()
+		{
+			return Measurements;
 
 		}
 
@@ -554,124 +574,121 @@ namespace OTSIncAReportApp._1_UI.OTSReportExport.DataIntegration
 		/// 定义ParticleData类
 		/// </summary>
 		public void newParticleData(OTSReport_Export m_otsreport_export)
-        {
-            fielddata = new ParticleData(m_otsreport_export.m_ReportApp.m_rstDataMgr.ResultFilesList[m_otsreport_export.m_ReportApp.m_rstDataMgr.GetWorkingResultId()].FilePath);
-        }
-        public ParticleData getParticleData()
-        {
-            return fielddata;
-        }
-        public void SetAllElement()
-        {
-            AllElement = fielddata.GetAllElement();
-        }
-        /// <summary>
-        /// 获取全部元素
-        /// </summary>
-        /// <returns></returns>
-        public DataTable GetAllElement()
-        {
-            return AllElement;
-        }
-        /// <summary>
-        /// 判断是否有大分类,有为true
-        /// </summary>
-        /// <param name="m_otsreport_export"></param>
-        /// <returns></returns>
-        public void IsThereAMajorClassification(BasicData basicData, OTSReport_Export m_otsreport_export)
-        {
-            //List<string> ClassName = ObtainParticleCategory(m_otsreport_export, basicData);
-            List<string> ClassName = new List<string>();
+		{
+			fielddata = new ParticleData(m_otsreport_export.m_ReportApp.m_rstDataMgr.ResultFilesList[m_otsreport_export.m_ReportApp.m_rstDataMgr.GetWorkingResultId()].FilePath);
+		}
+		public ParticleData getParticleData()
+		{
+			return fielddata;
+		}
+		public void SetAllElement()
+		{
+			AllElement = fielddata.GetAllElement();
+		}
+		/// <summary>
+		/// 获取全部元素
+		/// </summary>
+		/// <returns></returns>
+		public DataTable GetAllElement()
+		{
+			return AllElement;
+		}
+		/// <summary>
+		/// 判断是否有大分类,有为true
+		/// </summary>
+		/// <param name="m_otsreport_export"></param>
+		/// <returns></returns>
+		public void IsThereAMajorClassification(BasicData basicData, OTSReport_Export m_otsreport_export)
+		{
+			List<string> ClassName = new List<string>();
 
 			for (int i = 0; i < BData.Count; i++)
-            {
-                if (BData[i].Rows.Count != 0)
-                {
-                    ClassName.Add(i.ToString());
+			{
+				if (BData[i].Rows.Count != 0)
+				{
+					ClassName.Add(i.ToString());
 				}
-            }
+			}
 
 			if (ClassName.Count < 2)
-            {
-                IsShereAClassificationGroup= false;
-            }
-            else
-            {
-                IsShereAClassificationGroup= true;
-            }
-        }
-        public bool GetIsThereAMajorClassification()
-        {
-            return IsShereAClassificationGroup;
-        }
-		
+			{
+				IsShereAClassificationGroup = false;
+			}
+			else
+			{
+				IsShereAClassificationGroup = true;
+			}
+		}
+		public bool GetIsThereAMajorClassification()
+		{
+			return IsShereAClassificationGroup;
+		}
+
+
 
 		public void IsResultFilesList(OTSReport_Export m_otsreport_export)
-        {
-            resfile = m_otsreport_export.m_ReportApp.m_rstDataMgr.ResultFilesList[m_otsreport_export.m_ReportApp.m_rstDataMgr.GetWorkingResultId()];
-        }
-        /// <summary>
-        /// 获取标准库名称
-        /// </summary>
-        /// <returns></returns>
-        public string GetResfile()
-        {
-            string str_libraryName = "";
-            bool endsWithDb = resfile.GetSTDName().EndsWith(".db", StringComparison.OrdinalIgnoreCase);
-            if (endsWithDb)
-            {
-                str_libraryName = resfile.GetSTDName();
-            }
-            else
-            {
-                str_libraryName = resfile.GetSTDName() + ".db";
+		{
+			resfile = m_otsreport_export.m_ReportApp.m_rstDataMgr.ResultFilesList[m_otsreport_export.m_ReportApp.m_rstDataMgr.GetWorkingResultId()];
+		}
+		/// <summary>
+		/// 获取标准库名称
+		/// </summary>
+		/// <returns></returns>
+		public string GetResfile()
+		{
+			string str_libraryName = "";
+			bool endsWithDb = resfile.GetSTDName().EndsWith(".db", StringComparison.OrdinalIgnoreCase);
+			if (endsWithDb)
+			{
+				str_libraryName = resfile.GetSTDName();
 			}
-                return str_libraryName;
-        }
-        public void IsFilePath(OTSReport_Export m_otsreport_export)
-        {
-            FilePath= m_otsreport_export.m_ReportApp.m_rstDataMgr.CurResultFile.FilePath;
-        }
-        /// <summary>
-        /// 得到文件路径
-        /// </summary>
-        /// <returns></returns>
-        public string GetFilePath()
-        {
-            return FilePath;
-        }
+			else
+			{
+				str_libraryName = resfile.GetSTDName() + ".db";
+			}
+			return str_libraryName;
+		}
+		public void IsFilePath(OTSReport_Export m_otsreport_export)
+		{
+			FilePath = m_otsreport_export.m_ReportApp.m_rstDataMgr.CurResultFile.FilePath;
+		}
+		/// <summary>
+		/// 得到文件路径
+		/// </summary>
+		/// <returns></returns>
+		public string GetFilePath()
+		{
+			return FilePath;
+		}
 
-        #region 内部函数
-        private string getWhere(string max, string min, string col, string partic)
-        {
-            if (col == "Area")
-            {
-                return col + ">=" + ((Convert.ToDouble(min) / 2) * (Convert.ToDouble(min) / 2) * Math.PI).ToString() + " and " + col + "<" + ((Convert.ToDouble(max) / 2) * (Convert.ToDouble(max) / 2) * Math.PI).ToString() + " and TypeId=" + partic;
+		#region 内部函数(保留原有两个)
+		private string getWhere(string max, string min, string col, string partic)
+		{
+			if (col == "Area")
+			{
+				return col + ">=" + ((Convert.ToDouble(min) / 2) * (Convert.ToDouble(min) / 2) * Math.PI).ToString() + " and " + col + "<" + ((Convert.ToDouble(max) / 2) * (Convert.ToDouble(max) / 2) * Math.PI).ToString() + " and TypeId=" + partic;
 
 			}
-            else
-            {
+			else
+			{
 				return col + ">=" + min + " and " + col + "<" + max + " and TypeId=" + partic;
 			}
-                
-        }
-        private DataTable InvalidRemoval(DataTable dt)
-        {
-            DataTable dataTable = dt.Copy();
-            dataTable.Clear();
-
-            for (int i = 0; i < dt.Rows.Count; i++)
-            {
-                if (Convert.ToInt32(dt.Rows[i]["TypeId"]) > 10)
-                {
-                    dataTable.Rows.Add(dt.Rows[i].ItemArray);
-                }
-            }
-            return dataTable;
-        }
-        #endregion
-
 
+		}
+		private DataTable InvalidRemoval(DataTable dt)
+		{
+			DataTable dataTable = dt.Copy();
+			dataTable.Clear();
 
-    }
-}
+			for (int i = 0; i < dt.Rows.Count; i++)
+			{
+				if (Convert.ToInt32(dt.Rows[i]["TypeId"]) > 10)
+				{
+					dataTable.Rows.Add(dt.Rows[i].ItemArray);
+				}
+			}
+			return dataTable;
+		}
+		#endregion
+	}
+}

+ 176 - 203
OTSIncAReportApp/1-UI/OTSReportExport/DataIntegration/ParticleList.cs

@@ -38,245 +38,218 @@ namespace OTSIncAReportApp._1_UI.OTSReportExport.DataIntegration
 		/// </summary>
 		/// <param name="m_mbszclass"></param>
 		/// <returns></returns>
-		public List<DataTable> Get_dev_kllb_data(c_TemplateClass m_mbszclass, OTSReport_Export m_otsreport_export,BasicData basicData,out List<DataTable> a_FilteredData)
+		public List<DataTable> Get_dev_kllb_data(c_TemplateClass m_mbszclass, OTSReport_Export m_otsreport_export, BasicData basicData, out List<DataTable> a_FilteredData)
 		{
-			
-			//------------------加载模块,获取数据-------------------------------------------------
+			// 初始化
+			a_FilteredData = new List<DataTable>();
+			var OutDt = new List<DataTable>();
+
 			string str_resultPath = m_otsreport_export.m_ReportApp.m_rstDataMgr.ResultFilesList[m_otsreport_export.m_ReportApp.m_rstDataMgr.GetWorkingResultId()].FilePath;
-			ParticleData fielddata = new ParticleData(m_otsreport_export.m_ReportApp.m_rstDataMgr.ResultFilesList[m_otsreport_export.m_ReportApp.m_rstDataMgr.GetWorkingResultId()].FilePath);
+			ParticleData fielddata = new ParticleData(str_resultPath);
 
-            List<DataTable> OutDt = new List<DataTable>();
-            a_FilteredData = new List<DataTable>();
+			var datas = basicData.GetMeasurements();
+			if (datas == null || datas.Count == 0) return OutDt;
+
+			// 预缓存:删除序列集合(提高查找速度)
+			HashSet<string> deleteSerialSet = null;
+			if (m_mbszclass?.M_KLLBXX?.list_str_kllb_DeleteClass_Serial != null)
+				deleteSerialSet = new HashSet<string>(m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass_Serial);
+			else
+				deleteSerialSet = new HashSet<string>();
+
+			// field image 缓存,避免重复读文件
+			var fieldImageCache = new Dictionary<string, Bitmap>(StringComparer.Ordinal);
+
+			for (int idx = 0; idx < datas.Count; idx++)
+			{
+				var dtMeasure = datas[idx];
+				if (dtMeasure == null) continue;
 
-			List<DataTable> datas = basicData.GetMeasurements();
-            for (int i = 0; i < datas.Count; i++)
-            {
 				int serialNumber = 1;
-				if (m_otsreport_export.m_ReportApp.m_RptConfigFile.Systype == OTS_SysType_ID.TCCleannessA/*|| m_otsreport_export.m_ReportApp.m_RptConfigFile.Systype == OTS_SysType_ID.BatteryCleannessA*/)
+
+				// 如果需要,补充 Hardness 列并从标准库映射
+				if (m_otsreport_export.m_ReportApp.m_RptConfigFile.Systype == OTS_SysType_ID.TCCleannessA)
 				{
-					datas[i].Columns.Add("Hardness", typeof(double));
-					datas[i].Columns.Add("Hardness_detailed");
-					DataTable dt_stl = new DataTable();
-					if (GetSTL(basicData.GetResfile(), out dt_stl, m_otsreport_export))
+					if (!dtMeasure.Columns.Contains("Hardness")) dtMeasure.Columns.Add("Hardness", typeof(double));
+					if (!dtMeasure.Columns.Contains("Hardness_detailed")) dtMeasure.Columns.Add("Hardness_detailed", typeof(string));
+
+					if (GetSTL(basicData.GetResfile(), out DataTable dt_stl, m_otsreport_export) && dt_stl != null)
 					{
-						for (int a = 0; a < datas[a].Rows.Count; a++)
+						// 构建映射:StrName => row
+						var stlMap = new Dictionary<string, DataRow>(StringComparer.Ordinal);
+						for (int r = 0; r < dt_stl.Rows.Count; r++)
+						{
+							var key = dt_stl.Rows[r]["StrName"]?.ToString();
+							if (!string.IsNullOrEmpty(key) && !stlMap.ContainsKey(key))
+								stlMap[key] = dt_stl.Rows[r];
+						}
+
+						// 遍历并赋值
+						for (int r = 0; r < dtMeasure.Rows.Count; r++)
 						{
-							for (int b = 0; b < dt_stl.Rows.Count; b++)
+							var typeName = dtMeasure.Rows[r]["TypeName"]?.ToString();
+							if (string.IsNullOrEmpty(typeName)) continue;
+							if (stlMap.TryGetValue(typeName, out DataRow mapRow))
 							{
-								if (datas[a].Rows[a]["TypeName"].ToString() == dt_stl.Rows[b]["TypeId"].ToString())
-								{
-									datas[a].Rows[a]["Hardness"] = Convert.ToDouble(dt_stl.Rows[b]["Hardness"]);
-									datas[a].Rows[a]["Hardness_detailed"] = dt_stl.Rows[b]["Hardness_detailed"];
-									break;
-								}
+								if (double.TryParse(mapRow["Hardness"]?.ToString(), out double h)) dtMeasure.Rows[r]["Hardness"] = h;
+								dtMeasure.Rows[r]["Hardness_detailed"] = mapRow["Hardness_detailed"];
 							}
 						}
 					}
 				}
 
-
-				#region 夹杂物筛选
-				for (int a = 0; a < m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass_Serial.Count; a++)
-                {
-					for (int b = datas[i].Rows.Count - 1; b >= 0; b--)
+				// 夹杂物按序列 id 删除(倒序删除)
+				if (deleteSerialSet.Count > 0)
+				{
+					for (int r = dtMeasure.Rows.Count - 1; r >= 0; r--)
 					{
-						if (m_mbszclass.M_KLLBXX.list_str_kllb_DeleteClass_Serial[a].ToString() == datas[i].Rows[b]["TypeId"].ToString())
-						{
-                            datas[i].Rows.RemoveAt(b);
-						}
+						var tid = dtMeasure.Rows[r]["TypeId"]?.ToString();
+						if (!string.IsNullOrEmpty(tid) && deleteSerialSet.Contains(tid))
+							dtMeasure.Rows.RemoveAt(r);
 					}
 				}
 
+				// 排序并生成 p1Data_b
+				DataTable table = dtMeasure.Copy();
+				DataView dvs = table.DefaultView;
+				dvs.Sort = m_mbszclass.M_KLLBXX.str_cb_kllb_sort_p1.ToString() + " DESC";
+				DataTable p1Data_b = dvs.ToTable();
 
-                #endregion
-                #region 安装选择的类型大小排序
-                DataTable table = datas[i].Copy();
-      
+				// 增加元素列等(保持原 AddElementColumn 行为)
+				DataTable p1Data = fielddata.AddElementColumn(p1Data_b, m_mbszclass);
 
-                DataView dvs = table.DefaultView;
+				// 准备 Largest20 表结构(只创建一次 per group)
+				DataTable DT_Largest20 = new DataTable { TableName = "Largest20" };
+				var cols = new[]
+				{
+			"pid","Size","Width","DMAX","DMIN","Class",
+			"ColName1","ColName2","ColName3","ColName4","ColName5","ColName6","ColName7","ColName8","ColName9","ColName10",
+			"ColVal1","ColVal2","ColVal3","ColVal4","ColVal5","ColVal6","ColVal7","ColVal8","ColVal9","ColVal10",
+			"p1","p2","p3","GroupName"
+		};
+				foreach (var c in cols)
+				{
+					if (c == "p1" || c == "p2" || c == "p3")
+						DT_Largest20.Columns.Add(c, typeof(Bitmap));
+					else
+						DT_Largest20.Columns.Add(c);
+				}
 
+				DataTable FilteredData = p1Data.Clone();
+				ImageProcessor imageProcessor = new ImageProcessor();
 
-                dvs.Sort = m_mbszclass.M_KLLBXX.str_cb_kllb_sort_p1.ToString() + " DESC";
-				
-
-
-                    DataTable p1Data_b = dvs.ToTable();
-				#endregion
-
-				#region 创建要插入数据库表结构
-				//插入模板需父子表,结构
-				// 帧图表
-				DataTable DT_field_dt = new DataTable();
-				DataColumn colpictid2 = new DataColumn("FieldId");
-				colpictid2.DataType = typeof(int);
-				DT_field_dt.Columns.Add(colpictid2);
-				//图像列
-				DataColumn colpict2 = new DataColumn("FieldImg");
-				colpict2.DataType = System.Type.GetType("System.Byte[]");
-				DT_field_dt.Columns.Add(colpict2);
-				//largest20表:(无关系表)       需要显示前20条带有显示能谱图像的颗粒表
-				DataTable DT_Largest20 = new DataTable();
-				DT_Largest20.TableName = "Largest20";
-				DT_Largest20.Columns.Add("pid");
-				DT_Largest20.Columns.Add("Size");
-				DT_Largest20.Columns.Add("Width");
-				DT_Largest20.Columns.Add("DMAX");
-				DT_Largest20.Columns.Add("DMIN");
-				DT_Largest20.Columns.Add("Class");
-				DT_Largest20.Columns.Add("ColName1");
-				DT_Largest20.Columns.Add("ColName2");
-				DT_Largest20.Columns.Add("ColName3");
-				DT_Largest20.Columns.Add("ColName4");
-				DT_Largest20.Columns.Add("ColName5");
-				DT_Largest20.Columns.Add("ColName6");
-				DT_Largest20.Columns.Add("ColName7");
-				DT_Largest20.Columns.Add("ColName8");
-				DT_Largest20.Columns.Add("ColName9");
-				DT_Largest20.Columns.Add("ColName10");
-				DT_Largest20.Columns.Add("ColVal1");
-				DT_Largest20.Columns.Add("ColVal2");
-				DT_Largest20.Columns.Add("ColVal3");
-				DT_Largest20.Columns.Add("ColVal4");
-				DT_Largest20.Columns.Add("ColVal5");
-				DT_Largest20.Columns.Add("ColVal6");
-				DT_Largest20.Columns.Add("ColVal7");
-				DT_Largest20.Columns.Add("ColVal8");
-				DT_Largest20.Columns.Add("ColVal9");
-				DT_Largest20.Columns.Add("ColVal10");
-				// 图像列
-				DT_Largest20.Columns.Add("p1", typeof(Bitmap));
-				DT_Largest20.Columns.Add("p2", typeof(Bitmap));
-				DT_Largest20.Columns.Add("p3", typeof(Bitmap));
-				DT_Largest20.Columns.Add("GroupName");
-				#endregion
+				// 遍历 p1Data,挑选并处理前 N 个(按模板配置)
+				int maxCount = Math.Max(0, m_mbszclass.M_KLLBXX.list_int_kllb_number);
+				for (int i_row = 0; i_row < p1Data.Rows.Count; i_row++)
+				{
+					var elementStr = p1Data.Rows[i_row]["Element"]?.ToString();
+					var typeName = p1Data.Rows[i_row]["TypeName"]?.ToString();
+					if (string.IsNullOrEmpty(elementStr) || string.Equals(typeName, "Not Identified", StringComparison.OrdinalIgnoreCase))
+						continue;
 
+					if (p1Data.Rows[i_row]["FieldId"] == null || p1Data.Rows[i_row]["ParticleId"] == null)
+						continue;
 
-				DataTable p1Data = fielddata.AddElementColumn(p1Data_b, m_mbszclass);
+					if (serialNumber > maxCount && maxCount > 0) break;
 
+					string str_fieldid = p1Data.Rows[i_row]["FieldId"].ToString();
+					string str_particleid = p1Data.Rows[i_row]["ParticleId"].ToString();
+					string str_typeid = p1Data.Rows[i_row]["TypeId"]?.ToString();
+					string str_typename = typeName;
 
-				#region 插入颗粒部份
-				DataTable FilteredData = p1Data.Clone();
-				ImageProcessor imageProcessor = new ImageProcessor();
-                for (int i_row = 0; i_row < p1Data.Rows.Count; i_row++)
-                {
-                    if (p1Data.Rows[i_row]["Element"].ToString() != "")
-                    {
-						if (p1Data.Rows[i_row].ItemArray[24].ToString() != "Not Identified")
+					if (str_fieldid == "-1") continue;
+
+					// 读取并缓存帧图(避免重复从磁盘读取)
+					Bitmap bp_field = null;
+					if (!fieldImageCache.TryGetValue(str_fieldid, out bp_field))
+					{
+						try
 						{
-							//获取颗粒的fieldid,和particleid
-							string str_fieldid = p1Data.Rows[i_row]["fieldid"].ToString();
-							string str_particleid = p1Data.Rows[i_row]["particleid"].ToString();
-							string str_typeid = p1Data.Rows[i_row]["TypeId"].ToString();
-							string str_typename = p1Data.Rows[i_row]["TypeName"].ToString();
-							string str_element = p1Data.Rows[i_row]["Element"].ToString();
-							//获取原始颗粒图像
-							//Bitmap bp_particle = new Bitmap(1, 1);
-							string str_path = str_resultPath + "\\FIELD_FILES\\";
-							string str_imagePath = str_path + "Field" + str_fieldid.ToString() + ".bmp";
-							if (str_fieldid == "-1")
-								continue;
-							if (serialNumber > m_mbszclass.M_KLLBXX.list_int_kllb_number)
-								continue;
-							Rectangle rectangle = new Rectangle()
-							{ X = Convert.ToInt32(p1Data.Rows[i_row]["RectLeft"]), Y = Convert.ToInt32(p1Data.Rows[i_row]["RectTop"]), Width = Convert.ToInt32(p1Data.Rows[i_row]["RectWidth"]), Height = Convert.ToInt32(p1Data.Rows[i_row]["RectHeight"]) };
-							Bitmap bp_field = fielddata.ReadImageFile(str_imagePath);
-							Bitmap bp_particle = fielddata.GetBitmapByParticle(bp_field, rectangle);
-							bp_particle = imageProcessor.ResizeImageWithPadding(bp_particle, 120, 120, System.Drawing.Color.White);
-							bp_particle.Tag = new List<string>() { p1Data.Rows[i_row]["FieldId"].ToString(), p1Data.Rows[i_row]["ParticleId"].ToString(), p1Data.Rows[i_row]["TypeId"].ToString() };
-							//获取该颗粒的xray能谱图像
-							DataTable DT_XR = ExportXRay(str_fieldid, str_particleid, fielddata);
-							//ElementIcons.Add(DT_XR);
-							System.Drawing.Bitmap bp_xraybp = ExportXRayBitmap(str_fieldid,
-									str_particleid, Convert.ToInt32(str_typeid), str_typename, fielddata);
-							Bitmap ls_xraybpnew = OTSIncAReportGraph.Class.DrawFunction.KiResizeImage(bp_xraybp, 700, 115);//能谱图处理
-							DataTable SegmentData = fielddata.GetSegment();
-							Bitmap BinaryParticles = ImageSplicer.ParticleBinaryDiagram(SegmentData, Convert.ToInt32(str_fieldid), Convert.ToInt32(str_particleid));
-							Bitmap BP = imageProcessor.ResizeImageWithPadding(BinaryParticles, 120, 120, System.Drawing.Color.White);
-							//获取该颗粒的二次放大处理图像
-							//Bitmap ls_processbitmap = OTSIncAReportGraph.Class.DrawFunction.GetReZoomBitmap(bp_particle);// (Bitmap)bp_particle.Clone();//待完善
-							//再将图像转成二进制流-------------------------------------------------------------------
-							//原图
-							MemoryStream newms_p1 = new MemoryStream();
-							bp_particle.Save(newms_p1, System.Drawing.Imaging.ImageFormat.Bmp);
-							//二次放大图
-							MemoryStream newms_p2 = new MemoryStream();
-							BP.Save(newms_p2, System.Drawing.Imaging.ImageFormat.Bmp);
-							//能谱图
-							MemoryStream newms_p3 = new MemoryStream();
-							ls_xraybpnew.Save(newms_p3, System.Drawing.Imaging.ImageFormat.Bmp);
-							//---------------------------------------------------------------------------------------                   
-							DataRow dr = DT_Largest20.NewRow();
-							dr["p1"] = bp_particle;
-							dr["p2"] = BP;
-							dr["p3"] = ls_xraybpnew;
-
-
-							newms_p1.Dispose();
-							newms_p2.Dispose();
-							newms_p3.Dispose();
-							dr["pid"] = serialNumber++.ToString();
-							//颗粒列表列中第一个可选参数
-							dr["Size"] = datatable_data(p1Data, i_row, m_mbszclass.M_KLLBXX.str_cb_kllb_sort_p1);
-							//这个参数没有用
-							dr["Width"] = p1Data.Rows[i_row]["rectwidth"].ToString();
-							//颗粒列表列中第二个可选参数
-							dr["DMAX"] = datatable_data(p1Data, i_row, m_mbszclass.M_KLLBXX.str_cb_kllb_sort_p2);
-							//颗粒列表列中第三个可选参数
-							dr["DMIN"] = datatable_data(p1Data, i_row, m_mbszclass.M_KLLBXX.str_cb_kllb_sort_p3);
-							//颗粒列表列中显示分类不可以选择
-							dr["Class"] = p1Data.Rows[i_row]["typename"].ToString();
-
-							dr["GroupName"] = p1Data.Rows[i_row]["GroupName"].ToString();
-							GetMaxElementFromDataTable(p1Data, i_row, out List<string> list_max_elementname, out List<double> list_max_elementvale);
-							double colVal = 0;
-							for (int a = 0; a < list_max_elementvale.Count; a++)
+							string str_imagePath = Path.Combine(str_resultPath, "FIELD_FILES", "Field" + str_fieldid + ".bmp");
+							if (File.Exists(str_imagePath))
+							{
+								bp_field = fielddata.ReadImageFile(str_imagePath);
+							}
+							else
 							{
-								colVal = colVal + Convert.ToDouble(list_max_elementvale[a]);
+								bp_field = new Bitmap(1, 1);
 							}
-							//元素1
-							dr["ColName1"] = list_max_elementname[0];
-							dr["ColVal1"] = ParameterNormalization(colVal, list_max_elementvale[0]);
-							//元素2
-							dr["ColName2"] = list_max_elementname[1];
-							dr["ColVal2"] = ParameterNormalization(colVal, list_max_elementvale[1]);
-							//元素3
-							dr["ColName3"] = list_max_elementname[2];
-							dr["ColVal3"] = ParameterNormalization(colVal, list_max_elementvale[2]);
-							//元素4
-							dr["ColName4"] = list_max_elementname[3];
-							dr["ColVal4"] = ParameterNormalization(colVal, list_max_elementvale[3]);
-							//元素5
-							dr["ColName5"] = list_max_elementname[4];
-							dr["ColVal5"] = ParameterNormalization(colVal, list_max_elementvale[4]);
-							//元素6
-							dr["ColName6"] = list_max_elementname[5];
-							dr["ColVal6"] = ParameterNormalization(colVal, list_max_elementvale[5]);
-							//元素7
-							dr["ColName7"] = list_max_elementname[6];
-							dr["ColVal7"] = ParameterNormalization(colVal, list_max_elementvale[6]);
-							//元素8
-							dr["ColName8"] = list_max_elementname[7];
-							dr["ColVal8"] = ParameterNormalization(colVal, list_max_elementvale[7]);
-							//元素6
-							dr["ColName9"] = list_max_elementname[8];
-							dr["ColVal9"] = ParameterNormalization(colVal, list_max_elementvale[8]);
-							//元素6
-							dr["ColName9"] = list_max_elementname[9];
-							dr["ColVal9"] = ParameterNormalization(colVal, list_max_elementvale[9]);
-							DT_Largest20.Rows.Add(dr);
-							FilteredData.Rows.Add(p1Data.Rows[i_row].ItemArray);
 						}
+						catch
+						{
+							bp_field = new Bitmap(1, 1);
+						}
+						fieldImageCache[str_fieldid] = bp_field;
+					}
+
+					// 裁剪颗粒并生成缩略图
+					Rectangle rectangle;
+					try
+					{
+						rectangle = new Rectangle()
+						{
+							X = Convert.ToInt32(p1Data.Rows[i_row]["RectLeft"]),
+							Y = Convert.ToInt32(p1Data.Rows[i_row]["RectTop"]),
+							Width = Convert.ToInt32(p1Data.Rows[i_row]["RectWidth"]),
+							Height = Convert.ToInt32(p1Data.Rows[i_row]["RectHeight"])
+						};
 					}
-			
+					catch
+					{
+						continue;
+					}
+
+					Bitmap bp_particle = fielddata.GetBitmapByParticle(bp_field, rectangle);
+					bp_particle = imageProcessor.ResizeImageWithPadding(bp_particle, 120, 120, System.Drawing.Color.White);
+					bp_particle.Tag = new List<string> { p1Data.Rows[i_row]["FieldId"].ToString(), p1Data.Rows[i_row]["ParticleId"].ToString(), p1Data.Rows[i_row]["TypeId"].ToString() };
+
+					// 能谱图及二次处理图像
+					Bitmap bp_xraybp = ExportXRayBitmap(str_fieldid, str_particleid, Convert.ToInt32(str_typeid ?? "0"), str_typename, fielddata);
+					Bitmap ls_xraybpnew = bp_xraybp != null ? OTSIncAReportGraph.Class.DrawFunction.KiResizeImage(bp_xraybp, 700, 115) : new Bitmap(1, 1);
+
+					DataTable SegmentData = fielddata.GetSegment();
+					Bitmap BinaryParticles = ImageSplicer.ParticleBinaryDiagram(SegmentData, Convert.ToInt32(str_fieldid), Convert.ToInt32(str_particleid));
+					Bitmap BP = imageProcessor.ResizeImageWithPadding(BinaryParticles, 120, 120, System.Drawing.Color.White);
+
+					// 构造行并填充
+					DataRow dr = DT_Largest20.NewRow();
+					dr["p1"] = bp_particle;
+					dr["p2"] = BP;
+					dr["p3"] = ls_xraybpnew;
+					dr["pid"] = serialNumber++.ToString();
+					dr["Size"] = datatable_data(p1Data, i_row, m_mbszclass.M_KLLBXX.str_cb_kllb_sort_p1);
+					dr["Width"] = p1Data.Rows[i_row]["rectwidth"]?.ToString();
+					dr["DMAX"] = datatable_data(p1Data, i_row, m_mbszclass.M_KLLBXX.str_cb_kllb_sort_p2);
+					dr["DMIN"] = datatable_data(p1Data, i_row, m_mbszclass.M_KLLBXX.str_cb_kllb_sort_p3);
+					dr["Class"] = p1Data.Rows[i_row]["typename"]?.ToString();
+					dr["GroupName"] = p1Data.Rows[i_row]["GroupName"]?.ToString();
+
+					// 获取元素并归一化
+					GetMaxElementFromDataTable(p1Data, i_row, out List<string> list_max_elementname, out List<double> list_max_elementvale);
+					double colVal = 0;
+					for (int a = 0; a < list_max_elementvale.Count; a++) colVal += list_max_elementvale[a];
+
+					for (int e = 0; e < 10; e++)
+					{
+						string nameCol = "ColName" + (e + 1);
+						string valCol = "ColVal" + (e + 1);
+						dr[nameCol] = e < list_max_elementname.Count ? list_max_elementname[e] : " ";
+						dr[valCol] = e < list_max_elementvale.Count ? ParameterNormalization(colVal, list_max_elementvale[e]) : "";
+					}
+
+					DT_Largest20.Rows.Add(dr);
+					FilteredData.Rows.Add(p1Data.Rows[i_row].ItemArray);
 				}
-                #endregion
-                OutDt.Add(DT_Largest20);
-                a_FilteredData.Add(FilteredData);
+
+				OutDt.Add(DT_Largest20);
+				a_FilteredData.Add(FilteredData);
 			}
+
+			// 不要在这里释放缓存中的 Bitmap(调用方可能正在使用),由调用方负责释放生命周期
 			return OutDt;
 		}
 
-	
+
 		/// <summary>
 		/// 拼接颗粒
 		/// </summary>