using DevExpress.XtraEditors; using DevExpress.XtraSplashScreen; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Windows.Forms; using NPOI.SS.Util; using DeviceRepair.Models; using DeviceRepairAndOptimization.Models.Enum; using DeviceRepairAndOptimization.Biz; using DeviceRepairAndOptimization.Common; namespace DeviceRepairAndOptimization.Pages.Plan { public partial class page_PlanExcelImport : Form { #region 函数 public page_PlanExcelImport() { InitializeComponent(); SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true); } #endregion #region 属性 Dictionary keyValuePairs; StringBuilder logs = new StringBuilder(); string[] Keys = { "Monthly", "Annual", "Quarterly", "Semi-an" }; #endregion #region 事件 /// /// 底部panel控件 - 添加边框 /// /// /// private void panel_bottom_Paint(object sender, PaintEventArgs e) => (sender as Control).ControlBoardPoint(e, Direction.Up); /// /// 底部panel控件 - 添加边框 /// /// /// private void panel_top_Paint(object sender, PaintEventArgs e) => (sender as Control).ControlBoardPoint(e, Direction.Down); /// /// 页面加载完成 /// /// /// private void page_PlanExcelImport_Load(object sender, EventArgs e) { EditYear.ToYearStyle(); this.Invalidate(); this.FormBoardPoint(Direction.Left, Direction.Up, Direction.Right, Direction.Down); this.EditYear.Properties.NullValuePrompt = DateTime.Today.Year + ""; } /// /// 窗口关闭 /// /// /// private void btn_Close_Click(object sender, EventArgs e) => this.Close(); /// /// 重写窗口拖动 /// /// /// private void Form_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { ReleaseCapture(); PostMessage((int)this.Handle, WM_SysCommand, OneMsgNum, 0); } } /// /// 取消 /// /// /// private void btn_Exit_Click(object sender, EventArgs e) { this.Close(); } DateTime ClickTime; private void EditFilePath_Properties_Click(object sender, EventArgs e) { if (ClickTime == null || (DateTime.Now - ClickTime).TotalSeconds > 2) { //扩展 - 自定义待选择文件类型 OpenFileDialog ofd = new OpenFileDialog(); //自定义待选择文件类型 ofd.Filter = "Excel文件|*.xls;*.xlsx;*.xlsm;"; if (ofd.ShowDialog() == DialogResult.OK) { EditFilePath.Text = ofd.FileName; } } ClickTime = DateTime.Now; } /// /// 查看导入报错日志 /// /// /// private void lb_logs_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (logs.Length == 0) { XtraMessageBox.Show("当前没有日志信息!", "信息"); } else { new page_XtraFormLog("日志信息", logs).ShowDialog(); } } /// /// 导入的事件 /// /// /// private void btn_Import_Click(object sender, EventArgs e) { logs.Clear(); SplashScreenManager.ShowDefaultWaitForm("Excel导入中...", "请稍等..."); string filePath = EditFilePath.Text; DataTable dataTable = new DataTable(); if (string.IsNullOrEmpty(filePath)) { XtraMessageBox.Show("请选择待导入的文件", "错误"); return; } try { int CurrentMaintenanceYear = Convert.ToInt32(!string.IsNullOrWhiteSpace(EditYear.Text) ? EditYear.Text : DateTime.Today.Year + ""); APIResponseData apiResponseData = DeviceManager.Instance.GetQuery(""); if (!apiResponseData.IsSuccess) throw new Exception(apiResponseData.Message); List driveLst = apiResponseData.ToDeserializeObject>(); logs.AppendLine("正在打开Excel文件"); using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { IWorkbook workbook; if (Path.GetExtension(filePath) == ".xls") { logs.AppendLine("处理.xls文件"); workbook = new HSSFWorkbook(fs); // 处理.xls文件 } else if (Path.GetExtension(filePath) == ".xlsx") { logs.AppendLine("处理.xlsx文件"); workbook = new XSSFWorkbook(fs); // 处理.xlsx文件 } else { logs.AppendLine("不支持的文件格式"); SetWaitFormDescription(null, "操作失败,请重试"); Thread.Sleep(500); // 关闭等待窗口 SplashScreenManager.CloseDefaultWaitForm(); return; } logs.AppendLine("正在读取文件内容"); SetWaitFormDescription(null, "正在读取文件内容"); ISheet sheet = workbook.GetSheetAt(0); // 获取第一个工作表 if (sheet == null) { throw new Exception("不支持的文件格式"); } logs.AppendLine("获取第一个工作表"); logs.AppendLine("读取表头(第一行)并将其添加到 DataTable 中"); // 读取表头(第一行)并将其添加到 DataTable 中 if (sheet.LastRowNum == 0) { throw new Exception("不支持的文件格式"); } IRow headerRow = sheet.GetRow(0); for (int i = 0; i < headerRow.LastCellNum; i++) { ICell headerCell = headerRow.GetCell(i); if (headerCell != null) { dataTable.Columns.Add(headerCell.ToString()); } } SetWaitFormDescription(null, "文件读取完成"); Thread.Sleep(200); SetWaitFormDescription(null, "映射关系建立中"); bool hasError = false; logs.AppendLine("读取数据行并将其添加到 DataTable 中"); // 读取数据行并将其添加到 DataTable 中 for (int rowIndex = 1; rowIndex <= sheet.LastRowNum; rowIndex++) { try { IRow dataRow = sheet.GetRow(rowIndex); if (dataRow != null) { DataRow newRow = dataTable.NewRow(); if (dataRow.GetCell(0) == null) continue; for (int colIndex = 0; colIndex < dataRow.LastCellNum; colIndex++) { ICell cell = dataRow.GetCell(colIndex); if (cell != null) { if (cell.CellType == CellType.Numeric && DateUtil.IsCellDateFormatted(cell)) { // 将单元格值转换为日期 DateTime dateValue = cell.DateCellValue; newRow[colIndex] = dateValue; } else { newRow[colIndex] = cell.ToString(); } } } #region 校验设备信息 DeviceInformationInfo di = driveLst.Where(x => x.EquipmentID.Equals((newRow[0] + ""), StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault(); if (di == null) { hasError = true; throw new Exception($"不存在设备编号为:{(newRow[0] + "")}的设备!"); } newRow[0] = di.EquipmentID; #endregion #region 校验计划是否冲突 apiResponseData = PlanManager.Instance.GetPlanRecordProgress(di.AutoID, CurrentMaintenanceYear); if (apiResponseData.IsSuccess) { List progress = apiResponseData.ToDeserializeObject>(); if (progress != null && progress.Count > 0) { foreach (PlanProgress item in progress) { if (newRow[Enum.Parse(typeof(enumMonth), item.PlanMonth + "") + ""] + "" != item.PlanType) { hasError = true; throw new Exception($"设备编号为:{(newRow[0] + "")}的设备中,存在已保养{Enum.Parse(typeof(enumMonth), item.PlanMonth + "")}月份的年度数据,无法修改!"); } } } } #endregion dataTable.Rows.Add(newRow); } } catch (Exception ex) { logs.AppendLine($"行{rowIndex}出现错误:{ex.Message}"); } } if (hasError) { throw new Exception("导入的数据存在错误!"); } //读取键值对 KeyValuePairsBind(); List lst = new List(); logs.AppendLine("数据对应关系映射开始..."); int NotFoundCount = 0; foreach (DataRow item in dataTable.Rows) { string EquipmentID = item[keyValuePairs["EquipmentID"]] + ""; DeviceInformationInfo di = driveLst.Where(x => x.EquipmentID == EquipmentID).FirstOrDefault(); if (lst.Any(x => x.EquipmentID == di.AutoID)) { //logs.AppendLine($"设备编号为:{EquipmentID}的设备数据,在表格中存在多条!"); throw new Exception($"设备编号为:{EquipmentID}的设备数据,在表格中存在多条!"); } if (di != null) { foreach (KeyValuePair kvp in keyValuePairs) { enumMonth em; if (Enum.TryParse(kvp.Value, out em) //&& !string.IsNullOrEmpty(item[kvp.Value] + "") ) { DriveMaintencePlanInfo itemModel = new DriveMaintencePlanInfo { EquipmentID = di.AutoID, CompleteDate = null, MaintenanceYear = Convert.ToInt32(!string.IsNullOrWhiteSpace(EditYear.Text) ? EditYear.Text : DateTime.Today.Year + ""), MaintenanceMonth = (int)em, MaintenanceType = item[kvp.Value] + "", Remarks = item[keyValuePairs["Comment"]] + "", PMStartMonth = null, CreatDate = DateTime.Today, CreatUser = GlobalInfo.CurrentUser.AutoID, ChangeDate = DateTime.Today, ChangeUser = GlobalInfo.CurrentUser.AutoID }; DateTime pMStartMonth = DateTime.Now; if (DateTime.TryParse((item[keyValuePairs["StartMonth"]] + ""), out pMStartMonth)) { itemModel.PMStartMonth = pMStartMonth; } lst.Add(itemModel); } } } else { NotFoundCount++; logs.AppendLine($"程序中不存在设备编号为:{EquipmentID}的设备数据."); } } SetWaitFormDescription(null, "开始保存!"); if (lst.Count == 0 && NotFoundCount > 0) throw new Exception("导入的设备编号不存在!"); else if (lst.Count == 0) throw new Exception("导入的数据为空!"); apiResponseData = PlanManager.Instance.InsertDatas(lst); if (apiResponseData.IsSuccess) { SplashScreenManager.Default.SetWaitFormCaption("操作成功"); SplashScreenManager.Default.SetWaitFormDescription(""); Thread.Sleep(800); SplashScreenManager.CloseDefaultWaitForm(); DialogResult = DialogResult.OK; this.Close(); } else { throw new Exception(apiResponseData.Message); } } } catch (Exception ex) { HasErrorAndExitAction(ex.Message); logs.AppendLine(ex.Message); XtraMessageBox.Show(ex.Message, "错误"); } } /// /// 模板下载 /// /// /// private void lb_DownLoadTemplate_Click(object sender, EventArgs e) { FolderBrowserDialog dlg = new FolderBrowserDialog(); if (dlg.ShowDialog() == DialogResult.OK) { try { OutExcel(dlg.SelectedPath.ToString()); XtraMessageBox.Show("导出成功!", "信息"); } catch (Exception ex) { XtraMessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } #endregion #region 拖动窗口 #region WinAPI private const int WM_SysCommand = 0x0112; private const int OneMsgNum = 0xf017; [DllImport("user32")] private static extern bool ReleaseCapture(); [DllImport("user32")] private static extern bool PostMessage(int hWnd, int Mwg, int wParam, int lParam); #endregion #endregion 拖动窗口 #region 方法 /// /// 设置等待窗口文字 /// /// /// void SetWaitFormDescription(string caption, string content) { Invoke(new Action(() => { if (!string.IsNullOrWhiteSpace(caption)) SplashScreenManager.Default.SetWaitFormCaption(caption); if (!string.IsNullOrWhiteSpace(content)) SplashScreenManager.Default.SetWaitFormDescription(content); })); } void HasErrorAndExitAction(string Content) { SplashScreenManager.Default.SetWaitFormCaption("导入出错:"); SplashScreenManager.Default.SetWaitFormDescription(Content); Thread.Sleep(800); // 关闭等待窗口 SplashScreenManager.CloseDefaultWaitForm(); lb_logs.Visible = true; } /// /// 反射model类键值对 /// void KeyValuePairsBind() { if (keyValuePairs == null || keyValuePairs.Count == 0) { if (keyValuePairs == null) keyValuePairs = new Dictionary(); PropertyInfo[] properties = typeof(DriveMaintenancePlanExcelModel).GetProperties(); foreach (PropertyInfo item in properties) { DisplayNameAttribute[] attrs = (DisplayNameAttribute[])item.GetCustomAttributes(typeof(DisplayNameAttribute), true); keyValuePairs.Add(item.Name, attrs[0].DisplayName); } } } /// /// 导出模板 /// /// void OutExcel(string savePath) { // 创建Excel工作簿和工作表 IWorkbook workbook = new XSSFWorkbook(); ISheet sheet = workbook.CreateSheet($"OEM设备PM计划"); ISheet sheet2 = workbook.CreateSheet($"选项列表"); //读取Model属性生成键值对 KeyValuePairsBind(); // 写入表头 IRow headerRow = sheet.CreateRow(0); int index = 0; // 创建一个下拉框选项列表 string[] options = new string[] { "", "Monthly", "Annual", "Quarterly", "Semi-an" }; // 设置下拉框选项为字符串类型 IRow row = sheet2.CreateRow(0); for (int i = 0; i < options.Length; i++) { ICell cell = row.CreateCell(i); cell.SetCellValue(options[i]); } // 创建下拉框选项列表 var validationHelper = sheet.GetDataValidationHelper(); IDataValidationConstraint constraint = validationHelper.CreateExplicitListConstraint(options); int StartCellIndex = 0, EndCellIndex = 0; foreach (KeyValuePair item in keyValuePairs) { if (item.Key == "Jan") StartCellIndex = index; else if (item.Key == "Dec") EndCellIndex = index; headerRow.CreateCell(index).SetCellValue(item.Value); index++; } CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 1048575, StartCellIndex, EndCellIndex); // 从第二行开始到最后一行,第一列 IDataValidation dataValidation = validationHelper.CreateValidation(constraint, cellRangeAddressList); dataValidation.ShowErrorBox = true; // 将下拉框数据验证对象应用到整列的每个单元格 sheet.AddValidationData(dataValidation); // 删除选项sheet workbook.RemoveSheetAt(workbook.GetSheetIndex(sheet2)); // 保存Excel文件 using (FileStream fs = new FileStream(Path.Combine(savePath, $"保养计划模板-{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx"), FileMode.Create, FileAccess.Write)) { workbook.Write(fs); } } #endregion } }