上位机开发最烦和PLC对轴的位置,点的位置,一大堆的手写工序,数据不是放在Excel表,就是放在txt或者ini
图1.
图2
这次的需求
我需要手动将图1的数据写到图2
太麻烦
所以我准备写一个工具实现它
首先,我打算生成图2,需要使用到XML反序列化,读取图1,我使用MiniExcel
所以我先准备三个类
// 用于标记根元素
[XmlRoot("AxisPositionGroupItem")]
public class AxisPositionGroupItem
{// 使用XmlAttributeAttribute标记属性为XML属性[XmlAttribute("GroupName")]public string GroupName { get; set; }// 使用XmlElementAttribute标记属性为XML元素[XmlElement("AxisPositionItem")]public AxisPositionItem[] AxisPositionItems { get; set; }
}// 用于标记AxisPositionItem元素
public class AxisPositionItem
{[XmlAttribute("Label")]public string Label { get; set; }[XmlAttribute("AxisName")]public string AxisName { get; set; }[XmlAttribute("AxisId")]public string AxisId { get; set; } = "45";[XmlAttribute("AxisType")]public string AxisType { get; set; } = "PLC";[XmlAttribute("GroupName")]public string GroupName { get; set; }[XmlAttribute("Value")]public string Value { get; set; } = "68";[XmlAttribute("Speed")]public string Speed { get; set; } = "20";[XmlAttribute("SpeedDescription")]public string SpeedDescription { get; set; }=string.Empty;[XmlAttribute("PosIndex")]public int PosIndex { get; set; }
}public class AxisConfig{[ExcelColumnName("轴号")]public string AxisNumber { get; set; }[ExcelColumnName("轴名称")]public string AxisName { get; set; }[ExcelColumnName("功能名称")]public string FunctionName { get; set; }[ExcelColumnName("位置")]public string Position { get; set; }}
然后先获取Excel表格的数据
public class MiNiHelper{public static List<AxisConfig> ReadExcel(){var config = new OpenXmlConfiguration(){FillMergedCells = true};string path = "xxxxxx";var lists=MiniExcel.Query<AxisConfig>(path,"MotionParaInfo", configuration: config).ToList();var newList=lists.Where(x => x.Position != null).Where(y => y.AxisName != null).Where(z => z.FunctionName != null).ToList();return newList;}}
注意Where不能写在var lists=MiniExcel.Query
接下来,我们准备前端界面,看看效果
<Grid><ListView Margin="20" ItemsSource="{Binding DataList}"><ListView.View><GridView><GridViewColumnWidth="80"DisplayMemberBinding="{Binding AxisNumber}"Header="轴号" /><GridViewColumnWidth="180"DisplayMemberBinding="{Binding AxisName}"Header="轴名称" /><GridViewColumnWidth="280"DisplayMemberBinding="{Binding FunctionName}"Header="功能名称" /><GridViewColumnWidth="280"DisplayMemberBinding="{Binding Position}"Header="位置" /></GridView></ListView.View></ListView></Grid>
ViewModel代码
private ObservableCollection<AxisConfig> _dataList;public ObservableCollection<AxisConfig> DataList{get { return _dataList; }set { SetProperty(ref _dataList, value); }}DataList= MiNiHelper.ReadExcel().ToObservableCollection();
可以看到界面已经有了数据,说明我们成功了第一步。
现在我们测试一下,本地的XML生成
public class XMLHelper{public static void WriteMemory(){XmlSerializer serializer = new XmlSerializer(typeof(AxisPositionGroupItem));using (StringWriter writer = new StringWriter()){AxisPositionGroupItem groupItem = new AxisPositionGroupItem{GroupName = "UnLoad",AxisPositionItems = new AxisPositionItem[]{new AxisPositionItem{Label = "待机(安全)位置",AxisName = "ULD_TurnZ",AxisType = "PLC",GroupName = "ULD_TurnZ",SpeedDescription = "",PosIndex = "1"},// 其他 AxisPositionItem 对象...}};serializer.Serialize(writer, groupItem);string xml = writer.ToString();}}
}
然后将数据传递过去,修改WriteLocal
/// <summary>
/// 使用MiniExcel读取的数据
/// </summary>
/// <param name="axisConfigs"></param>
public static void WriteLocal(List<AxisConfig> axisConfigs)
{XmlSerializer serializer = new XmlSerializer(typeof(AxisPositionGroupItem));// 创建 AxisPositionGroupItem 对象AxisPositionGroupItem groupItem = new AxisPositionGroupItem{GroupName = "UnLoad",AxisPositionItems = axisConfigs.Select(config => new AxisPositionItem{Label = config.FunctionName,AxisName = config.AxisName,GroupName = config.AxisName, // 假设 AxisName 和 GroupName 保持一致AxisId = "45", // 如果轴号是固定的,可以直接赋值AxisType = "PLC",Value = "68", // 如果 Value 是固定的,可以直接赋值Speed = "20", // 如果 Speed 是固定的,可以直接赋值SpeedDescription = string.Empty, // 如果 SpeedDescription 没有值,可以直接赋值PosIndex = ExtractPosIndex(config.Position) // 假设轴号是整数,并且对应 PosIndex}).ToArray()};// 使用 StringWriter 来序列化对象using (StringWriter writer = new StringWriter()){serializer.Serialize(writer, groupItem);string xml = writer.ToString();// 指定要保存的文件路径string filePath = @"E:\CSharp Project\自定义习题\反序列化XML\file.xml";// 使用 StreamWriter 将字符串写入文件using (StreamWriter fileWriter = new StreamWriter(filePath)){fileWriter.Write(xml);}Console.WriteLine("XML has been saved to " + filePath);}
}
public static string ExtractPosIndex(string axisPosition)
{// 使用LINQ删除中括号并获取最后一个字符string lastString = new string(axisPosition.Where(c => c != '[' && c != ']').ToArray()).LastOrDefault().ToString();// string last = axisPosition.Replace("[", "").Replace("]", "");// 获取最后一个字符// string lastString = last[last.Length - 1].ToString();return lastString;throw new ArgumentException("无法从轴位置字符串中提取PosIndex。");
}
接下来修改ViewModel代码
public MainViewModel(){Init();}private void Init(){DataList= MiNiHelper.ReadExcel().ToObservableCollection();var axisConfigs=MiNiHelper.ReadExcel();XMLHelper.WriteLocal(axisConfigs);}
完成