上位機開發最煩和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);
}
完成