575 lines
23 KiB
C#
575 lines
23 KiB
C#
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<string, string> keyValuePairs;
|
||
|
||
StringBuilder logs = new StringBuilder();
|
||
|
||
string[] Keys = { "Monthly", "Annual", "Quarterly", "Semi-an" };
|
||
|
||
#endregion
|
||
|
||
#region 事件
|
||
|
||
/// <summary>
|
||
/// 底部panel控件 - 添加边框
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void panel_bottom_Paint(object sender, PaintEventArgs e) =>
|
||
(sender as Control).ControlBoardPoint(e, Direction.Up);
|
||
|
||
/// <summary>
|
||
/// 底部panel控件 - 添加边框
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void panel_top_Paint(object sender, PaintEventArgs e) =>
|
||
(sender as Control).ControlBoardPoint(e, Direction.Down);
|
||
|
||
/// <summary>
|
||
/// 页面加载完成
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
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 + "";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 窗口关闭
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void btn_Close_Click(object sender, EventArgs e) => this.Close();
|
||
|
||
/// <summary>
|
||
/// 重写窗口拖动
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void Form_MouseMove(object sender, MouseEventArgs e)
|
||
{
|
||
if (e.Button == MouseButtons.Left)
|
||
{
|
||
ReleaseCapture();
|
||
PostMessage((int)this.Handle, WM_SysCommand, OneMsgNum, 0);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
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(this) == DialogResult.OK)
|
||
{
|
||
EditFilePath.Text = ofd.FileName;
|
||
}
|
||
}
|
||
|
||
ClickTime = DateTime.Now;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查看导入报错日志
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void lb_logs_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||
{
|
||
if (logs.Length == 0)
|
||
{
|
||
XtraMessageBoxHelper.Info("当前没有日志信息!", "信息");
|
||
}
|
||
else
|
||
{
|
||
new page_XtraFormLog("日志信息", logs).ShowDialog(this);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导入的事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
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))
|
||
{
|
||
XtraMessageBoxHelper.Error("请选择待导入的文件");
|
||
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<DeviceInformationInfo> driveLst = apiResponseData.ToDeserializeObject<List<DeviceInformationInfo>>();
|
||
|
||
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);
|
||
|
||
if (headerRow == null)
|
||
{
|
||
throw new Exception("首行数据获取失败,导入的模板不正确!");
|
||
}
|
||
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))
|
||
{
|
||
try
|
||
{
|
||
// 将单元格值转换为日期
|
||
DateTime dateValue = cell.DateCellValue;
|
||
newRow[colIndex] = dateValue;
|
||
}
|
||
catch
|
||
{
|
||
logs.AppendLine($"行{rowIndex}出现错误输入的【新PM起始月份】非日期格式!");
|
||
hasError = true;
|
||
}
|
||
}
|
||
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<PlanProgress> progress = apiResponseData.ToDeserializeObject<List<PlanProgress>>();
|
||
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<DriveMaintencePlanInfo> lst = new List<DriveMaintencePlanInfo>();
|
||
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<string, string> 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);
|
||
XtraMessageBoxHelper.Error(ex.Message);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 模板下载
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void lb_DownLoadTemplate_Click(object sender, EventArgs e)
|
||
{
|
||
FolderBrowserDialog dlg = new FolderBrowserDialog();
|
||
if (dlg.ShowDialog(this) == DialogResult.OK)
|
||
{
|
||
try
|
||
{
|
||
OutExcel(dlg.SelectedPath.ToString());
|
||
XtraMessageBoxHelper.Info("导出成功!");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
XtraMessageBoxHelper.Error(ex.Message);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
#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 方法
|
||
|
||
/// <summary>
|
||
/// 设置等待窗口文字
|
||
/// </summary>
|
||
/// <param name="caption"></param>
|
||
/// <param name="content"></param>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 反射model类键值对
|
||
/// </summary>
|
||
void KeyValuePairsBind()
|
||
{
|
||
if (keyValuePairs == null || keyValuePairs.Count == 0)
|
||
{
|
||
if (keyValuePairs == null)
|
||
keyValuePairs = new Dictionary<string, string>();
|
||
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导出模板
|
||
/// </summary>
|
||
/// <param name="savePath"></param>
|
||
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<string, string> 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
|
||
}
|
||
} |