革博士V2程序
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

932 righe
45 KiB

  1. using ClosedXML.Excel;
  2. using LeatherApp.Utils;
  3. using Models;
  4. using Newtonsoft.Json.Linq;
  5. using Service;
  6. using SqlSugar;
  7. using Sunny.UI;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.ComponentModel;
  11. using System.Data;
  12. using System.Drawing;
  13. using System.Drawing.Imaging;
  14. using System.IO;
  15. using System.Linq;
  16. using System.Linq.Expressions;
  17. using System.Text;
  18. using System.Threading.Tasks;
  19. using System.Windows.Forms;
  20. namespace LeatherApp.Page
  21. {
  22. public partial class FReport : UIPage
  23. {
  24. RecordsService service=new RecordsService();
  25. ProductService productService =new ProductService();
  26. public FReport( )
  27. {
  28. InitializeComponent();
  29. uiDatePicker1.Value = DateTime.Now.AddMonths(-1);
  30. uiDatePicker2.Value=DateTime.Now;
  31. this.lineChartDefect.Size = new Size(600,800);
  32. this.lineChartFaceWidth.Size = new Size(1000, 300);
  33. #region dataGridView设置
  34. uiDataGridView1.AutoGenerateColumns = false;//自动创建列
  35. uiDataGridView1.AllowUserToAddRows = uiDataGridView1.AllowUserToDeleteRows = false;//用户添加删除行
  36. uiDataGridView1.AllowUserToResizeRows = true;//用户调整行大小
  37. uiDataGridView1.AllowUserToResizeColumns = false;//用户调整列大小
  38. uiDataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;//只可选中整行,不是单元格
  39. //显示行号与列宽度自动调整
  40. uiDataGridView1.RowHeadersVisible = true;
  41. uiDataGridView1.RowHeadersWidth = 30;
  42. uiDataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;//数据量过百绑定太变
  43. uiDataGridView1.RowPostPaint += (sender, e) =>//序号列头
  44. {
  45. Utils.Util.showRowNum_onDataGrid_RowPostPaint(this.uiDataGridView1, sender, e);
  46. };
  47. uiDataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
  48. //for (int i = 0; i < dataGridView1.Columns.Count; i++)//禁止点击列头排序
  49. // uiDataGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
  50. //行列交叉处标题
  51. //if (uiDataGridView1.RowHeadersVisible) uiDataGridView1.TopLeftHeaderCell.Value = "SPH/CYL";
  52. //事件
  53. this.uiDataGridView1.DataBindingComplete += this.uiDataGridView1_DataBindingComplete;//bing data时发生,可修改单元格内容
  54. //this.uiDataGridView1.SelectIndexChange += uiDataGridView1_SelectIndexChange;//选择行时发行
  55. //this.uiDataGridView1.CellClick += UiDataGridView1_CellClick;
  56. #endregion
  57. #region 分页及页脚合计设置
  58. this.uiPagination1.PageChanged += new Sunny.UI.UIPagination.OnPageChangeEventHandler(this.uiPagination1_PageChanged);
  59. //设置分页控件每页数量
  60. uiPagination1.PageSize = 20;
  61. //设置统计绑定的表格
  62. //uiDataGridViewFooter1.DataGridView = uiDataGridView1;
  63. //激活第1第,触发uiPagination1_PageChanged
  64. uiPagination1.ActivePage = 1;
  65. #endregion
  66. }
  67. private Expression<Func<Records, bool>> createQueryExpression()
  68. {
  69. return Expressionable.Create<Records>()
  70. .And(it => it.CreateTime >= uiDatePicker1.Value.SetTime(0,0,0))
  71. .And(it => it.CreateTime < uiDatePicker2.Value.SetTime(0, 0, 0).AddDays(1))
  72. .AndIF(!string.IsNullOrWhiteSpace(txtBarcode.Text), it => it.BarCode.Contains(txtBarcode.Text.Trim()))
  73. .AndIF(!string.IsNullOrWhiteSpace(txtBatchId.Text), it => it.BatchId.Contains(txtBatchId.Text.Trim()))
  74. .AndIF(!string.IsNullOrWhiteSpace(txtReelId.Text), it => it.ReelId.Contains(txtReelId.Text.Trim()))
  75. .ToExpression();//注意 这一句 不能少
  76. }
  77. /// <summary>
  78. /// 分页控件页面切换事件
  79. /// </summary>
  80. /// <param name="sender"></param>
  81. /// <param name="pagingSource"></param>
  82. /// <param name="pageIndex"></param>
  83. /// <param name="count"></param>
  84. private void uiPagination1_PageChanged(object sender, object pagingSource, int pageIndex, int count)
  85. {
  86. //未连接数据库,通过模拟数据来实现
  87. //一般通过ORM的分页去取数据来填充
  88. //pageIndex:第几页,和界面对应,从1开始,取数据可能要用pageIndex
  89. //count:单页数据量,也就是PageSize值
  90. int totalCount = 0;
  91. var list = service.GetListNav(pageIndex , count, ref totalCount, createQueryExpression());
  92. uiDataGridView1.DataSource = list;
  93. uiPagination1.TotalCount = totalCount;
  94. //表脚合计
  95. //uiDataGridViewFooter1.Clear();
  96. //uiDataGridViewFooter1["Column1"] = "合计:";
  97. //uiDataGridViewFooter1["Column2"] = "Column2_" + pageIndex;
  98. //uiDataGridViewFooter1["Column3"] = "Column3_" + pageIndex;
  99. //uiDataGridViewFooter1["Column4"] = "Column4_" + pageIndex;
  100. //
  101. //this.uiDataGridView1.CurrentCell = null;
  102. //this.uiDataGridView1.ClearSelection();
  103. }
  104. private void uiDataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
  105. {
  106. var list = uiDataGridView1.DataSource as List<Records>;
  107. for (int i = 0; i < uiDataGridView1.Rows.Count; i++)
  108. {
  109. if (list[i].Grade < 1) uiDataGridView1.Rows[i].Cells["colGrade"].Value = "";
  110. else if (list[i].Grade <= 5) uiDataGridView1.Rows[i].Cells["colGrade"].Value = (char)(list[i].Grade+64);
  111. else uiDataGridView1.Rows[i].Cells["colGrade"].Value = "不合格";
  112. //if (list[i].RoleInfo != null)
  113. // uiDataGridView1.Rows[i].Cells["colRoleName"].Value = list[i].RoleInfo.Name;
  114. }
  115. }
  116. private void btnQuery_Click(object sender, EventArgs e)
  117. {
  118. uiPagination1.ActivePage = 1;
  119. }
  120. private void btnExport_Click(object sender, EventArgs e)
  121. {
  122. try
  123. {
  124. if (this.uiDataGridView1.CurrentRow == null)
  125. return;
  126. Models.Records record = service.GetModelNav(int.Parse(this.uiDataGridView1.CurrentRow.Cells[0].Value.ToString()));
  127. if (record.DefectInfoList.Count < 0)
  128. throw new Exception("当前记录无缺陷!");
  129. string path = FileUtil.selectFolder();
  130. if (string.IsNullOrWhiteSpace(path))
  131. return;
  132. //var list = uiDataGridView1.DataSource as List<Records>;
  133. //var table = ExcelUtil.ConvertToDataTable<Records>(list);
  134. //{ 名称=x.Name,Xcm=x.X,Ym=x.Y/100,宽cm=x.Width,高cm=x.Height,面积=x.Area, 置信度 =x.ZXD}
  135. var list = record.DefectInfoList;//.Select(x => new { x.Name,x.X,x.Y,x.Width,x.Height,x.Area, x.ZXD}).ToList();
  136. //绘图1
  137. double len = Math.Round(record.Len*100, 2);//cm
  138. this.reDrawDefectPoints(record.DefectInfoList, new double[] { 0, Math.Round(record.FaceWidthMax + 0.005f, 2) }, new double[] { 0, len });
  139. //绘图2
  140. //var points = Array.ConvertAll(record.FaceWidthListStr.Split(new[] { ',', }, StringSplitOptions.RemoveEmptyEntries),Double.Parse).ToList();
  141. //reDrawFaceWidth(record.FacePointList,
  142. // new double[] { 0, Math.Round(len + 0.005f, 2) },
  143. // new double[] { record.FaceWidthMin, Math.Round(record.FaceWidthMax + 0.005f, 2) });
  144. reDrawFaceWidth(record.FacePointList,
  145. new double[] { 0, Math.Round(len + 0.005f, 2) },
  146. new double[] { 130, 160 });
  147. //
  148. foreach (var item in list) {
  149. item.Name = Config.getDefectName(item.Code);
  150. //item.Height = item.Height / 100; //单位错误,保证单位一致
  151. }
  152. //
  153. string Grade = "";
  154. if (record.Grade < 1) Grade = "";
  155. else if (record.Grade <= 5) Grade = (char)(record.Grade + 64)+"";
  156. else Grade = "不合格";
  157. JsonProductDefects data = new JsonProductDefects()
  158. {
  159. ProName = record.BarCodeName,
  160. BatchId = record.BatchId,
  161. ReelId = record.ReelId,
  162. Len = record.Len.ToString(),
  163. Speed = Math.Round(record.Len / record.TimeLen, 2).ToString(),
  164. Grade= Grade,
  165. DateTime = record.CreateTime.ToString("yyyy年MM月dd日 HH:mm")
  166. };
  167. data.DefectTotal = record.DefectInfoList.GroupBy(x => x.Name).Select(g => new JDefectTotal { Name = g.Key,Count=g.Count() }).ToList();
  168. data.DefectDetail = record.DefectInfoList.Select(x => new JDefectDetail {
  169. Index=x.PhotoIndex,Name=x.Name, X=x.X,Y=Math.Round(x.Y/100.0d,2),Width=x.Width * 10,Height=x.Height * 10,ZXD=x.ZXD,Area=x.Area * 100,Contrast=x.Contrast })
  170. .OrderBy(x=>x.Index).ThenBy(x=>x.Y).ToList();
  171. data.Pdt = productService.GetModelNav(record.ProductId);
  172. data.xyPix = $"X:{Config.cm2px_x},Y:{Config.cm2px_y}";
  173. var image1 = captureControl(this.lineChartDefect);
  174. var image2 = captureControl(this.lineChartFaceWidth);
  175. var filePath = $"{path}缺陷列表_{record.BatchId}_{record.ReelId}.xlsx";
  176. exportTabel(data, image1, image2, filePath);
  177. //if (!res)
  178. // throw new Exception("导出失败!");
  179. UIMessageTip.ShowOk("导出成功!", 1000);
  180. System.Diagnostics.Process.Start(filePath);
  181. }
  182. catch (Exception ex)
  183. {
  184. UIMessageTip.ShowError(ex.Message, 2000);
  185. API.OutputDebugString(ex.StackTrace);
  186. }
  187. }
  188. private void btnExport_Click1(object sender, EventArgs e)
  189. {
  190. try
  191. {
  192. if (this.uiDataGridView1.CurrentRow == null)
  193. return;
  194. Models.Records record = service.GetModelNav(int.Parse(this.uiDataGridView1.CurrentRow.Cells[0].Value.ToString()));
  195. if (record.DefectInfoList.Count < 0)
  196. throw new Exception("当前记录无缺陷!");
  197. string path = FileUtil.selectFolder();
  198. if (string.IsNullOrWhiteSpace(path))
  199. return;
  200. //var list = uiDataGridView1.DataSource as List<Records>;
  201. //var table = ExcelUtil.ConvertToDataTable<Records>(list);
  202. //{ 名称=x.Name,Xcm=x.X,Ym=x.Y/100,宽cm=x.Width,高cm=x.Height,面积=x.Area, 置信度 =x.ZXD}
  203. var list = record.DefectInfoList;//.Select(x => new { x.Name,x.X,x.Y,x.Width,x.Height,x.Area, x.ZXD}).ToList();
  204. foreach (var item in list)
  205. {
  206. item.Name = Config.getDefectName(item.Code);
  207. item.Height = item.Height / 100;
  208. }
  209. var table = ExcelUtil.ConvertToDataTable<DefectInfo>(list, new List<string> { "PhotoIndex", "Name", "ZXD", "Contrast", "X", "Y", "Width", "Height", "Area" });
  210. for (int i = 0; i < table.Columns.Count; i++)
  211. {
  212. switch (table.Columns[i].ColumnName)
  213. {
  214. case "PhotoIndex":
  215. table.Columns[i].ColumnName = "源图";
  216. break;
  217. case "Name":
  218. table.Columns[i].ColumnName = "名称";
  219. break;
  220. case "ZXD":
  221. table.Columns[i].ColumnName = "置信度";
  222. break;
  223. case "Contrast":
  224. table.Columns[i].ColumnName = "对比度";
  225. break;
  226. case "X":
  227. table.Columns[i].ColumnName = "X(cm)";
  228. break;
  229. case "Y":
  230. table.Columns[i].ColumnName = "Y(cm)";
  231. break;
  232. case "Width":
  233. table.Columns[i].ColumnName = "宽(cm)";
  234. break;
  235. case "Height":
  236. table.Columns[i].ColumnName = "长度(米)";
  237. break;
  238. case "Area":
  239. table.Columns[i].ColumnName = "面积(cm^2)";
  240. break;
  241. }
  242. }
  243. ExcelUtil.DataTable2CSV($"{path}\\缺陷列表_{record.BarCodeName}.csv", table);
  244. UIMessageTip.ShowOk("导出成功!", 1000);
  245. }
  246. catch (Exception ex)
  247. {
  248. UIMessageTip.ShowError(ex.Message, 2000);
  249. }
  250. }
  251. public void exportTabel(JsonProductDefects ProductDefects, byte[] defectImage, byte[] faceWidthImage,string savePath)
  252. {
  253. //try
  254. //{
  255. if (ProductDefects == null)
  256. throw new Exception("传入的参数为空");
  257. using (var workbook = new XLWorkbook())
  258. {
  259. var wsDefectsDetail = workbook.Worksheets.Add("正面疵点列表");
  260. wsDefectsDetail.RowHeight = 20;
  261. wsDefectsDetail.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
  262. wsDefectsDetail.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
  263. wsDefectsDetail.Style.Font.FontName = "宋体";
  264. wsDefectsDetail.Column("A").Width = 12;
  265. wsDefectsDetail.Column("B").Width = 25;
  266. wsDefectsDetail.Column("C").Width = 10;
  267. wsDefectsDetail.Column("D").Width = 10;
  268. wsDefectsDetail.Column("E").Width = 10;
  269. wsDefectsDetail.Column("F").Width = 10;
  270. wsDefectsDetail.Column("G").Width = 12;
  271. wsDefectsDetail.Column("H").Width = 14;
  272. wsDefectsDetail.Column("I").Width = 14;
  273. int rowIndex = 1;
  274. int cellIndex = 1;
  275. #region 第一行
  276. var row1_cell1 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex);
  277. row1_cell1.Value = "产品疵点缺陷分布图表";
  278. row1_cell1.Style.Font.Bold = true;
  279. //row1_cell1.Style.Font.FontName = "宋体";
  280. row1_cell1.Style.Font.FontSize = 12;
  281. var mergeRange_row1 = wsDefectsDetail.Range("A1:I1").Row(1).Merge();
  282. mergeRange_row1.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  283. #endregion
  284. #region 第二行
  285. rowIndex++;
  286. var row2_cell1 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex);
  287. row2_cell1.Value = "产品品名";
  288. row2_cell1.Style.Font.Bold = true;
  289. row2_cell1.Style.Font.FontSize = 10;
  290. row2_cell1.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  291. var row2_cell2 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 1);
  292. row2_cell2.DataType = XLDataType.Text;
  293. row2_cell2.Value = ProductDefects.ProName;
  294. row2_cell2.Style.Font.FontSize = 10;
  295. row2_cell2.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  296. var row2_cell3 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 2);
  297. row2_cell3.Value = "产品批号";
  298. row2_cell3.Style = row2_cell1.Style;
  299. var row2_cell4 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 3);
  300. row2_cell4.Value = "'" + ProductDefects.BatchId;
  301. row2_cell4.Style = row2_cell2.Style;
  302. var row2_cell5 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 4);
  303. row2_cell5.Value = "产品卷号";
  304. row2_cell5.Style = row2_cell1.Style;
  305. var row2_cell6 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 5);
  306. //row2_cell6.SetDataType(XLDataType.Text);//类型设置不起作用 用"'"+内容代替
  307. //row2_cell6.DataType = XLDataType.Text;
  308. row2_cell6.Value = "'" + ProductDefects.ReelId;
  309. row2_cell6.Style = row2_cell2.Style;
  310. var row2_cell7 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 6);
  311. row2_cell7.Value = "长度(米)";
  312. row2_cell7.Style = row2_cell1.Style;
  313. var row2_cell8 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 7);
  314. row2_cell8.Value = ProductDefects.Len;
  315. row2_cell8.Style = row2_cell2.Style;
  316. //NULL
  317. var row2_cell9 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 8);
  318. row2_cell9.Style = row2_cell2.Style;
  319. #endregion
  320. #region 第三行
  321. rowIndex++;
  322. var row3_cell1 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex);
  323. row3_cell1.Value = "检验时间";
  324. row3_cell1.Style = row2_cell1.Style;
  325. var row3_cell2 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 1);
  326. row3_cell2.Value = "'" + ProductDefects.DateTime;
  327. row3_cell2.Style = row2_cell2.Style;
  328. var row3_cell3 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 2);
  329. row3_cell3.Value = "检验长度";
  330. row3_cell3.Style = row2_cell1.Style;
  331. var row3_cell4 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 3);
  332. row3_cell4.Value = ProductDefects.Len;
  333. row3_cell4.Style = row2_cell2.Style;
  334. var row3_cell5 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 4);
  335. row3_cell5.Value = "平均速度";
  336. row3_cell5.Style = row2_cell1.Style;
  337. var row3_cell6 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 5);
  338. row3_cell6.Value = ProductDefects.Speed;
  339. row3_cell6.Style = row2_cell2.Style;
  340. var row3_cell7 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 6);
  341. row3_cell7.Value = "等级";
  342. row3_cell7.Style = row2_cell1.Style;
  343. var row3_cell8 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 7);
  344. row3_cell8.Value = ProductDefects.Grade;
  345. row3_cell8.Style = row2_cell2.Style;
  346. var row3_cell9 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 8);
  347. row3_cell9.Style = row2_cell2.Style;
  348. #endregion
  349. #region 第四第五行
  350. rowIndex++;
  351. var row4_cell1 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex);
  352. row4_cell1.Value = "设备参数";
  353. row4_cell1.Style = row2_cell1.Style;
  354. row4_cell1.Style.Font.Bold = true;
  355. row4_cell1.Style.Font.FontSize = 10;
  356. row4_cell1.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  357. var mergeRange_row4 = wsDefectsDetail.Range("A4:A5").Column(1).Merge();
  358. mergeRange_row4.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  359. var row4_cell2 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 1);
  360. row4_cell2.Value = "光源亮度";
  361. row4_cell2.Style = row2_cell1.Style;
  362. var row4_cell3 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 2);
  363. row4_cell3.Value = "曝光时间";
  364. row4_cell3.Style = row2_cell1.Style;
  365. var row4_cell4 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 3);
  366. row4_cell4.Value = "增益";
  367. row4_cell4.Style = row2_cell1.Style;
  368. var row4_cell5 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 4);
  369. row4_cell5.Value = "行频比";
  370. row4_cell5.Style = row2_cell1.Style;
  371. var row4_cell6 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 5);
  372. row4_cell6.Value = "物面分辨率";
  373. row4_cell6.Style = row2_cell1.Style;
  374. var row4_cell7 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 6);
  375. row4_cell7.Value = "触发计数";
  376. row4_cell7.Style = row2_cell1.Style;
  377. var row4_cell8 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 7);
  378. row4_cell8.Value = "采集计数";
  379. row4_cell8.Style = row2_cell1.Style;
  380. var row4_cell9 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 8);
  381. row4_cell9.Value = "";
  382. row4_cell9.Style = row2_cell1.Style;
  383. rowIndex++;
  384. var row5_cell2 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 1);
  385. row5_cell2.Value = ProductDefects.Pdt.LightValue;
  386. row5_cell2.Style = row2_cell1.Style;
  387. var row5_cell3 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 2);
  388. row5_cell3.Value = ProductDefects.Pdt.ExposureTime;
  389. row5_cell3.Style = row2_cell1.Style;
  390. var row5_cell4 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 3);
  391. row5_cell4.Value = ProductDefects.Pdt.Gain;
  392. row5_cell4.Style = row2_cell1.Style;
  393. var row5_cell5 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 4);
  394. row5_cell5.Value = "";
  395. row5_cell5.Style = row2_cell1.Style;
  396. var row5_cell6 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 5);
  397. row5_cell6.Value = ProductDefects.xyPix;
  398. row5_cell6.Style = row2_cell1.Style;
  399. var row5_cell7 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 6);
  400. row5_cell7.Value = "";
  401. row5_cell7.Style = row2_cell1.Style;
  402. var row5_cell8 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 7);
  403. row5_cell8.Value = "";
  404. row5_cell8.Style = row2_cell1.Style;
  405. var row5_cell9 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 8);
  406. row5_cell9.Value = "";
  407. row5_cell9.Style = row2_cell1.Style;
  408. #endregion
  409. #region 第六行后
  410. rowIndex++;
  411. if (ProductDefects.DefectTotal != null && ProductDefects.DefectTotal.Count > 0)
  412. {
  413. cellIndex = 1;
  414. int DefectTotalCount = ProductDefects.DefectTotal.Count;
  415. //最少5行,固定4列
  416. var row6_cell1 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex);
  417. row6_cell1.Value = "检测参数";
  418. row6_cell1.Style.Font.Bold = true;
  419. row6_cell1.Style.Font.FontSize = 10;
  420. row6_cell1.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  421. string cellstr = $"A6:A{7 + ProductDefects.DefectTotal.Count}";
  422. var mergeRange_row6 = wsDefectsDetail.Range(cellstr).Column(1).Merge();
  423. mergeRange_row6.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  424. var row6_cell2 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 1);
  425. row6_cell2.Value = "筛选标准";
  426. row6_cell2.Style.Font.Bold = true;
  427. row6_cell2.Style.Font.FontSize = 10;
  428. row6_cell2.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  429. var mergeRange_row6_2 = wsDefectsDetail.Range($"B6:I6").Row(1).Merge();
  430. mergeRange_row6_2.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  431. //第七行
  432. rowIndex++;
  433. var row7_cell2 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 1);
  434. row7_cell2.Value = "缺陷类型";
  435. row7_cell2.Style = row2_cell1.Style;
  436. var row7_cell3 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 2);
  437. row7_cell3.Value = "置信度";
  438. row7_cell3.Style = row2_cell1.Style;
  439. var row7_cell4 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 3);
  440. row7_cell4.Value = "面积";
  441. row7_cell4.Style = row2_cell1.Style;
  442. var row7_cell5 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 4);
  443. row7_cell5.Value = "对比度下限";
  444. row7_cell5.Style = row2_cell1.Style;
  445. var row7_cell6 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 5);
  446. row7_cell6.Value = "对比度上限";
  447. row7_cell6.Style = row2_cell1.Style;
  448. var row7_cell7 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 6);
  449. row7_cell7.Value = "所用模型版本";
  450. row7_cell7.Style = row2_cell1.Style;
  451. var row7_cell8 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 7);
  452. row7_cell8.Value = "或向选择";
  453. row7_cell8.Style = row2_cell1.Style;
  454. var row7_cell9 = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + 8);
  455. row7_cell9.Value = "本次检出数量";
  456. row7_cell9.Style = row2_cell1.Style;
  457. //第八行之后
  458. rowIndex++;
  459. for (int j = 1; j <= ProductDefects.DefectTotal.Count; j++) // 行
  460. {
  461. var temprowcel2 = wsDefectsDetail.Row(rowIndex + j - 1).Cell(cellIndex + 1);
  462. var temprowcel3 = wsDefectsDetail.Row(rowIndex + j - 1).Cell(cellIndex + 2);
  463. var temprowcel4 = wsDefectsDetail.Row(rowIndex + j - 1).Cell(cellIndex + 3);
  464. var temprowcel5 = wsDefectsDetail.Row(rowIndex + j - 1).Cell(cellIndex + 4);
  465. var temprowcel6 = wsDefectsDetail.Row(rowIndex + j - 1).Cell(cellIndex + 5);
  466. var temprowcel7 = wsDefectsDetail.Row(rowIndex + j - 1).Cell(cellIndex + 6);
  467. var temprowcel8 = wsDefectsDetail.Row(rowIndex + j - 1).Cell(cellIndex + 7);
  468. var temprowcel9 = wsDefectsDetail.Row(rowIndex + j - 1).Cell(cellIndex + 8);
  469. var tempItemDefectTotal = ProductDefects.DefectTotal[j - 1];
  470. temprowcel2.Value = tempItemDefectTotal.Name;
  471. temprowcel2.Style.Font.Bold = true;
  472. temprowcel2.Style.Font.FontSize = 10;
  473. temprowcel2.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  474. var temp = ProductDefects.Pdt.QualifiedLimitList.Find(x => Config.getDefectName(x.Code) == tempItemDefectTotal.Name);
  475. temprowcel3.Value = temp.ZXD;
  476. temprowcel3.Style.Font.Bold = true;
  477. temprowcel3.Style.Font.FontSize = 10;
  478. temprowcel3.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  479. temprowcel4.Value = temp.Area;
  480. temprowcel4.Style.Font.Bold = true;
  481. temprowcel4.Style.Font.FontSize = 10;
  482. temprowcel4.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  483. temprowcel5.Value = ContrastToPercent(temp.ContrastLower);
  484. temprowcel5.Style.Font.Bold = true;
  485. temprowcel5.Style.Font.FontSize = 10;
  486. temprowcel5.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  487. temprowcel6.Value = ContrastToPercent(temp.ContrastTop);
  488. temprowcel6.Style.Font.Bold = true;
  489. temprowcel6.Style.Font.FontSize = 10;
  490. temprowcel6.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  491. temprowcel7.Value = ProductDefects.Pdt.ModelName;
  492. temprowcel7.Style.Font.Bold = true;
  493. temprowcel7.Style.Font.FontSize = 10;
  494. temprowcel7.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  495. temprowcel8.Value = temp.IsOR;
  496. temprowcel8.Style.Font.Bold = true;
  497. temprowcel8.Style.Font.FontSize = 10;
  498. temprowcel8.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  499. temprowcel9.Value = tempItemDefectTotal.Count;
  500. temprowcel9.Style.Font.FontSize = 10;
  501. temprowcel9.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  502. }
  503. //更新行号
  504. rowIndex = rowIndex + ProductDefects.DefectTotal.Count;
  505. }
  506. #endregion
  507. #region 最后
  508. //rowIndex++;
  509. if (ProductDefects.DefectDetail != null && ProductDefects.DefectDetail.Count > 0)
  510. {
  511. List<string> lstRow5str = new List<string>() { "源图", "名称", "X(cm)", "Y(米)", "宽(mm)", "高(mm)", "置信度", "面积(mm^2)", "对比度" };
  512. for (int i = 0; i < lstRow5str.Count; i++)
  513. {
  514. var temp_row5_cell = wsDefectsDetail.Row(rowIndex).Cell(cellIndex + i);
  515. temp_row5_cell.Value = lstRow5str[i];
  516. temp_row5_cell.Style.Font.Bold = true;
  517. temp_row5_cell.Style.Font.FontSize = 11;
  518. temp_row5_cell.Style.Font.FontName = "等线";
  519. temp_row5_cell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  520. }
  521. rowIndex++;
  522. for (int i = 0; i < ProductDefects.DefectDetail.Count; i++)
  523. for (int j = 0; j < lstRow5str.Count; j++)
  524. {
  525. var temp_row6_cell = wsDefectsDetail.Row(rowIndex + i).Cell(cellIndex + j);
  526. switch (lstRow5str[j])
  527. {
  528. case "源图":
  529. temp_row6_cell.Value = ProductDefects.DefectDetail[i].Index;
  530. break;
  531. case "名称":
  532. temp_row6_cell.Value = ProductDefects.DefectDetail[i].Name;
  533. break;
  534. case "X(cm)":
  535. temp_row6_cell.Value = ProductDefects.DefectDetail[i].X;
  536. break;
  537. case "Y(米)":
  538. temp_row6_cell.Value = ProductDefects.DefectDetail[i].Y;
  539. break;
  540. case "宽(mm)":
  541. temp_row6_cell.Value = ProductDefects.DefectDetail[i].Width;
  542. break;
  543. case "高(mm)":
  544. temp_row6_cell.Value = ProductDefects.DefectDetail[i].Height;
  545. break;
  546. case "置信度":
  547. temp_row6_cell.Value = ProductDefects.DefectDetail[i].ZXD;
  548. break;
  549. case "面积(mm^2)":
  550. temp_row6_cell.Value = ProductDefects.DefectDetail[i].Area;
  551. break;
  552. case "对比度":
  553. temp_row6_cell.Value = ProductDefects.DefectDetail[i].Contrast;
  554. break;
  555. }
  556. temp_row6_cell.Style.Font.FontSize = 11;
  557. temp_row6_cell.Style.Font.FontName = "等线";
  558. temp_row6_cell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
  559. }
  560. // row6_cell1.InsertTable(ProductDefects.DefectDetail);
  561. }
  562. #endregion
  563. var wsDefectsImg = workbook.Worksheets.Add("正面疵点分布图");
  564. wsDefectsImg.AddPicture(new MemoryStream(defectImage), "纵向计算")
  565. .MoveTo(wsDefectsImg.Cell(1, 1));
  566. var wsFaceWidthImg = workbook.Worksheets.Add("门幅曲线");
  567. wsFaceWidthImg.AddPicture(new MemoryStream(faceWidthImage), "幅宽曲线图")
  568. .MoveTo(wsFaceWidthImg.Cell(1, 1));
  569. workbook.SaveAs(savePath);
  570. }
  571. // return true;
  572. //}
  573. //catch (Exception ex)
  574. //{
  575. // return false;
  576. //}
  577. }
  578. private double ContrastLow = 0.8;
  579. private double ContrastTop = 1.2;
  580. private double ContrastToPercent(double val)
  581. {
  582. if (val < ContrastLow)
  583. return 0;
  584. else if (val > ContrastTop)
  585. return 100;
  586. double temp = 100 / (ContrastTop - ContrastLow);
  587. return Math.Round(temp * (val - ContrastLow), 2);
  588. }
  589. public static Image getImageBase64(string imgBase64)
  590. {
  591. byte[] imgByte = Convert.FromBase64String(imgBase64);
  592. Stream stream = new MemoryStream(imgByte);
  593. return Image.FromStream(stream);
  594. }
  595. public class JsonProductDefects
  596. {
  597. [Description("产品品名")]
  598. public string ProName { get; set; }
  599. [Description("产品批号")]
  600. public string BatchId { get; set; }
  601. [Description("产品卷号")]
  602. public string ReelId { get; set; }
  603. [Description("检验长度")]
  604. public string Len { get; set; }
  605. [Description("平均速度")]
  606. public string Speed { get; set; }
  607. [Description("等级")]
  608. public string Grade { get; set; }
  609. [Description("检验时间")]
  610. public string DateTime { get; set; }
  611. [Description("疵点统计")]
  612. public List<JDefectTotal> DefectTotal = new List<JDefectTotal>();
  613. public List<JDefectDetail> DefectDetail = new List<JDefectDetail>();
  614. [Description("检测设置")]
  615. public Product Pdt { get; set; }
  616. [Description("物面分辨率")]
  617. public string xyPix { get; set; }
  618. }
  619. public class JDefectTotal
  620. {
  621. [Description("疵点名")]
  622. public string Name { get; set; }
  623. [Description("疵点数")]
  624. public int Count { get; set; }
  625. }
  626. public class JDefectDetail
  627. {
  628. [Description("源图")]
  629. public int Index { get; set; }
  630. [Description("名称")]
  631. public string Name { get; set; }
  632. [Description("X(cm)")]
  633. public double X { get; set; }
  634. [Description("Y(米)")]
  635. public double Y { get; set; }
  636. [Description("宽(cm)")]
  637. public double Width { get; set; }
  638. [Description("高(cm)")]
  639. public double Height { get; set; }
  640. [Description("置信度")]
  641. public double ZXD { get; set; }
  642. [Description("面积(cm^2)")]
  643. public double Area { get; set; }
  644. [Description("对比度")]
  645. public double Contrast { get; set; }
  646. }
  647. //
  648. /// <summary>
  649. /// 重新生成缺陷分布(cm2M在内部转换)
  650. /// </summary>
  651. /// <param name="lstDefectInfo">Records.DefectInfoList</param>
  652. /// <param name="XSizeRange">幅宽</param>
  653. /// <param name="YSizeRange">卷长度</param>
  654. private void reDrawDefectPoints(List<DefectInfo> lstDefectInfo, double[] XSizeRange, double[] YSizeRange)
  655. {
  656. UILineOption option;
  657. //AddTextEvent($"绘图", $"缺陷分布, W={string.Join(", ", XSizeRange)},H={string.Join(", ", YSizeRange)}, LastData={JsonConvert.SerializeObject(lstDefectInfo[lstDefectInfo.Count - 1])}");
  658. var lstData = lstDefectInfo.OrderBy(m => m.Code).ThenBy(m => m.Code).ToList();
  659. if (XSizeRange == null || YSizeRange == null)
  660. option = this.lineChartDefect.Option;
  661. else
  662. {
  663. if (YSizeRange[0] == YSizeRange[1])
  664. {
  665. YSizeRange[0] -= YSizeRange[0] / 10f;
  666. YSizeRange[1] += YSizeRange[1] / 10f;
  667. }
  668. YSizeRange[0] /= 100;
  669. YSizeRange[1] /= 100;
  670. option = new UILineOption();
  671. option.XAxis.Name = "面宽(cm)";
  672. option.YAxis.Name = "长度(米)";
  673. //option.Grid.Top = 20;//边距
  674. option.Grid.Right = 20;//边距
  675. //X轴数据类型
  676. option.XAxisType = UIAxisType.Value;
  677. //设置X/Y轴显示范围
  678. option.XAxis.SetRange(XSizeRange[0], XSizeRange[1]);
  679. option.YAxis.SetRange(YSizeRange[0], YSizeRange[1]);
  680. //坐标轴显示小数位数
  681. option.XAxis.AxisLabel.DecimalPlaces = option.YAxis.AxisLabel.DecimalPlaces = 1;
  682. //X/Y轴画参考线
  683. //option.YAxisScaleLines.Add(new UIScaleLine("上限", 3.5, Color.Red));
  684. //option.YAxisScaleLines.Add(new UIScaleLine("下限", 2.2, Color.Gold));
  685. //option.XAxisScaleLines.Add(new UIScaleLine(dt.AddHours(3).DateTimeString(), dt.AddHours(3), Color.Red));
  686. //option.XAxisScaleLines.Add(new UIScaleLine(dt.AddHours(6).DateTimeString(), dt.AddHours(6), Color.Red));
  687. option.ToolTip.Visible = true;
  688. //option.ToolTip.Formatter = "怎么自定义X,Y显示名称??{X}";
  689. option.Title = new UITitle();
  690. option.Title.Text = "";
  691. option.Title.SubText = "";
  692. }
  693. string preCode = "";
  694. UILineSeries series = null;
  695. foreach (var item in lstData)
  696. {
  697. if (preCode != item.Code)//加一组新类型及样式
  698. {
  699. preCode = item.Code;
  700. var one = Config.getDefectItem(item.Code);
  701. if (one == null)
  702. {
  703. continue;
  704. }
  705. JObject objItem = one as JObject;
  706. Color color = ColorTranslator.FromHtml(objItem.Value<string>("color"));
  707. series = option.AddSeries(new UILineSeries(objItem.Value<string>("name"), color));//加一组
  708. series.Symbol = UILinePointSymbol.Star;
  709. series.SymbolSize = 4;
  710. series.SymbolLineWidth = 2;
  711. series.ShowLine = false;
  712. series.SymbolColor = color;
  713. //数据点显示小数位数(针对当前UILineSeries)
  714. series.XAxisDecimalPlaces = 1;
  715. series.YAxisDecimalPlaces = 2;
  716. //series.Smooth = false;
  717. }
  718. series.Add(item.CentreX, item.CentreY / 100); //cm -> m
  719. }
  720. //====
  721. //option.GreaterWarningArea = new UILineWarningArea(3.5);
  722. //option.LessWarningArea = new UILineWarningArea(2.2, Color.Gold);
  723. //this.BeginInvoke(new System.Action(() =>
  724. //{
  725. this.lineChartDefect.SetOption(option);
  726. //series.UpdateYData();//按序号更新Y轴值(可设置值超出范围用于闪烁)
  727. //}));
  728. }
  729. /// <summary>
  730. /// 重新门幅宽度
  731. /// </summary>
  732. /// <param name="points"></param>
  733. /// <param name="XSizeRange">卷长度</param>
  734. /// <param name="YSizeRange">幅宽</param>
  735. private void reDrawFaceWidth(List<float[]> points, double[] XSizeRange, double[] YSizeRange)
  736. {
  737. //AddTextEvent($"绘图", $"门幅宽度, W={string.Join(", ", XSizeRange)},H={string.Join(", ", YSizeRange)}, LastData={JsonConvert.SerializeObject(points[points.Count-1])}");
  738. if (YSizeRange[0] == YSizeRange[1])
  739. {
  740. YSizeRange[0] -= YSizeRange[0] / 10f;
  741. YSizeRange[1] += YSizeRange[1] / 10f;
  742. }
  743. XSizeRange[0] /= 100;
  744. XSizeRange[1] /= 100;
  745. //防止超限
  746. XSizeRange[1] += 0.01;
  747. YSizeRange[1] += 0.1;
  748. UILineOption option = new UILineOption();
  749. option.XAxis.Name = "长度(米)";
  750. option.YAxis.Name = "面宽(cm)";
  751. option.Grid.Top = 20;
  752. option.Grid.Right = 20;
  753. //X轴数据类型
  754. option.XAxisType = UIAxisType.Value;
  755. //设置X/Y轴显示范围
  756. option.XAxis.SetRange(XSizeRange[0], XSizeRange[1]);
  757. option.YAxis.SetRange(YSizeRange[0], YSizeRange[1]);
  758. //坐标轴显示小数位数
  759. option.XAxis.AxisLabel.DecimalPlaces = option.YAxis.AxisLabel.DecimalPlaces = 1;
  760. //X/Y轴画参考线
  761. //option.YAxisScaleLines.Add(new UIScaleLine("上限", 3.5, Color.Red));
  762. //option.YAxisScaleLines.Add(new UIScaleLine("下限", 2.2, Color.Gold));
  763. //option.XAxisScaleLines.Add(new UIScaleLine(dt.AddHours(3).DateTimeString(), dt.AddHours(3), Color.Red));
  764. //option.XAxisScaleLines.Add(new UIScaleLine(dt.AddHours(6).DateTimeString(), dt.AddHours(6), Color.Red));
  765. option.ToolTip.Visible = true;
  766. //option.ToolTip.Formatter = "怎么自定义X,Y显示名称??{X}";
  767. option.Title = new UITitle();
  768. option.Title.Text = "";
  769. option.Title.SubText = "";
  770. Color color = Color.Blue;
  771. UILineSeries series = null;
  772. series = option.AddSeries(new UILineSeries("面宽", color));
  773. series.Symbol = UILinePointSymbol.Circle;
  774. series.ShowLine = true;
  775. series.SymbolSize = 4;
  776. series.SymbolLineWidth = 2;
  777. series.SymbolColor = color;
  778. //数据点显示小数位数(针对当前UILineSeries)
  779. series.XAxisDecimalPlaces = 2;
  780. series.YAxisDecimalPlaces = 1;
  781. float x;
  782. foreach (var item in points)
  783. {
  784. x = item[0] / 100; //cm -> m
  785. series.Add(x, item[1]);
  786. }
  787. //====
  788. //option.GreaterWarningArea = new UILineWarningArea(3.5);
  789. //option.LessWarningArea = new UILineWarningArea(2.2, Color.Gold);
  790. //this.BeginInvoke(new System.Action(() =>
  791. //{
  792. this.lineChartFaceWidth.SetOption(option);
  793. //}));
  794. }
  795. // 截图操作函数
  796. private byte[] captureControl(Control control)
  797. {
  798. Bitmap bmp = new Bitmap(control.Width, control.Height);
  799. Graphics graphics = Graphics.FromImage(bmp);
  800. Rectangle rectangle = new Rectangle(0, 0, control.Width, control.Height);
  801. control.DrawToBitmap(bmp, rectangle);
  802. //bmp to jpg
  803. MemoryStream ms = new MemoryStream();
  804. bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);//bmp是已经获得的bitmap数据
  805. byte[] bytes = ms.GetBuffer();
  806. ms.Close();
  807. graphics.Dispose();
  808. return bytes;
  809. //bitmap.Save(@"C:\Images\Capture.jpg", ImageFormat.Jpeg);
  810. //return Image.FromStream(new MemoryStream(bytes));
  811. }
  812. private void btnChar_Click(object sender, EventArgs e)
  813. {
  814. Frame.SelectPage(1004);
  815. }
  816. }
  817. }