DeviceManager/DeviceRepairAndOptimization/Pages/Plan/page_PlanExcelImport.cs
2024-06-04 17:25:13 +08:00

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
}
}