革博士程序V1仓库
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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