DeviceManager/DeviceRepairAndOptimization/Pages/Plan/page_PlanExcelImport.cs
2024-09-26 10:47:56 +08:00

575 lines
23 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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