革博士程序V1仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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