Files
SzmediTools/Szmedi.RvKits/InfoManager/PropEditor/MappingElementCodeViewModel.cs

222 lines
9.2 KiB
C#
Raw Normal View History

2025-09-16 16:06:41 +08:00

using System.Linq;
using System.Text;
using System.Windows;
using Autodesk.Revit.DB;
using EPPlus.Core.Extensions;
using Microsoft.Win32;
using Nice3point.Revit.Toolkit.External.Handlers;
using OfficeOpenXml;
namespace Szmedi.RvKits.ModelManager
{
public partial class MappingElementCodeViewModel : ObservableObject
{
private readonly ActionEventHandler handler = new();
[ObservableProperty]
private string excelPath;
[ObservableProperty]
private ExcelWorksheet selectedSheet;
[ObservableProperty]
private bool isFuzzyMatch = true;
[ObservableProperty]
private bool isIdMapping;
/// <summary>
/// 选择的列
/// </summary>
[ObservableProperty]
private KeyValuePair<int, string> selectedColumn;
[ObservableProperty]
private ExcelWorksheets sheets;
/// <summary>
/// 第一行,表头的数据
/// </summary>
[ObservableProperty]
private IEnumerable<KeyValuePair<int, string>> columns;
private ExcelPackage excelPackage;
[RelayCommand]
private void WriteParameters()
{
handler.Raise(uiapp =>
{
var sb = new StringBuilder();
var doc = uiapp.ActiveUIDocument.Document;
//匹配的元素在第几列
var col = SelectedColumn.Key;
//匹配的属性条目名称
var paramNameMapped = SelectedColumn.Value;
doc.InvokeGroup(
_ =>
{
//从第二行开始
for (int m = SelectedSheet.Dimension.Start.Row + 1, n = SelectedSheet.Dimension.End.Row; m <= n; m++)
{
//找到值
var val = SelectedSheet.GetValue(m, col);
Element elementMapped = null;
var excelValue = val.ToString();
if (paramNameMapped.ToUpper() == "ID")
{
if (IsFuzzyMatch)
{
excelValue = excelValue.Trim().ToLower();
}
var id = Convert.ToInt32(excelValue);
elementMapped = doc.GetElement(new ElementId(id));
if (elementMapped != null)
break;
}
else
{
elementMapped = doc.OfAllModelCollector()?.WhereElementIsNotElementType().FirstOrDefault(
e =>
{
if (e.GetParameters(paramNameMapped).Count == 0)
{
return false;
}
return e.GetParameters(paramNameMapped).Any(p =>
{
var paramValue = p.GetValue().ToString();
if (IsFuzzyMatch)
{
paramValue = paramValue.Trim().ToLower();
excelValue = excelValue.Trim().ToLower();
}
return paramValue == excelValue;
});
});
}
if (elementMapped == null)
{
sb.AppendLine(
$"工作簿:《{Path.GetFileNameWithoutExtension(ExcelPath)}》 表:<{SelectedSheet.Name}> 行号: {m} 未发现匹配的模型。");
continue;
}
//不存在的属性
var noExistProps = Columns.Where(
item => elementMapped.GetParameters(item.Value).Count == 0
&& item.Value.ToUpper() != "ID");
if (noExistProps.Any())
{
if (elementMapped is FamilyInstance instance)
{
if (!instance.Symbol.Family.IsEditable)
{
sb.AppendLine($"族不可编辑Id:{instance.Id}-类型名:{instance.Symbol.FamilyName}");
continue;
}
var famdoc = doc.EditFamily(instance.Symbol.Family);
famdoc.Invoke(
ts =>
{
foreach (var item in noExistProps)
{
famdoc.FamilyManager
.AddParameter(
item.Value,
BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES,
ParameterType.Text,
true);
}
},
"添加缺失的族参数属性条目");
famdoc.LoadFamily(doc, new FamilyLoadOption());
famdoc.Close(false);
}
else
{
doc.Invoke(ts =>
{
foreach (var item in noExistProps)
{
SharedParameterAssists.AddOrAttachSharedParameter(doc, item.Value, categories: elementMapped.Category);
}
}, "添加缺失的共享参数属性条目");
}
}
doc.Invoke(ts =>
{
foreach (var item in Columns)
{
var paramsToWrite = elementMapped.GetParameters(item.Value);
var v = SelectedSheet.GetValue(m, item.Key);
//if(paramToWrite == null)
//{
// //sb.AppendLine($"元素Id:[{elementMaped.Id}] 元素:{elementMaped.Name} 属性: {item.Value} 未发现。");
// continue;
//}
foreach (var param in paramsToWrite)
{
param?.SetValue(v);
}
}
},
"属性填写");
}
}, "属性匹配");
if (sb.Length > 0)
{
MessageBox.Show(sb.ToString(), "处理结果");
}
//LogAssists.WriteTxtFile("log", sb.ToString());
});
}
partial void OnSelectedSheetChanged(ExcelWorksheet value)
{
//第一行的所有列
Columns = value.GetColumns(1).Where(r => !string.IsNullOrEmpty(r.Value));
}
[RelayCommand]
private void OnDrop(DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files is { Length: > 0 })
{
ExcelPath = files[0]; // 读取文件路径并赋值给 FilePath 属性
}
}
}
[RelayCommand]
private void SelectExcelPath()
{
var dialog = new OpenFileDialog()
{
Filter = "Excel文件(*.xlsx)|*.xlsx",
Title = "请选择Excel文件",
};
if (dialog.ShowDialog() == true)
{
ExcelPath = dialog.FileName;
excelPackage = new(new System.IO.FileInfo(dialog.FileName));
Sheets = excelPackage.Workbook.Worksheets;
}
}
}
}