561 lines
22 KiB
C#
561 lines
22 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() == 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)
|
|
{
|
|
XtraMessageBox.Show("当前没有日志信息!", "信息");
|
|
}
|
|
else
|
|
{
|
|
new page_XtraFormLog("日志信息", logs).ShowDialog();
|
|
}
|
|
}
|
|
|
|
/// <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))
|
|
{
|
|
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<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);
|
|
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 == (newRow[0] + "")).FirstOrDefault();
|
|
if (di == null)
|
|
{
|
|
hasError = true;
|
|
throw new Exception($"不存在设备编号为:{(newRow[0] + "")}的设备!");
|
|
}
|
|
#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);
|
|
XtraMessageBox.Show(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() == 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 方法
|
|
|
|
/// <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
|
|
}
|
|
} |