和PLC对配置的繁琐工序
上位机开发最烦和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>
<GridViewColumn
Width="80"
DisplayMemberBinding="{Binding AxisNumber}"
Header="轴号" />
<GridViewColumn
Width="180"
DisplayMemberBinding="{Binding AxisName}"
Header="轴名称" />
<GridViewColumn
Width="280"
DisplayMemberBinding="{Binding FunctionName}"
Header="功能名称" />
<GridViewColumn
Width="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);
}
完成