using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO.Packaging; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using EPPlus.Core.Extensions; using Microsoft.Win32; using Nice3point.Revit.Toolkit.External.Handlers; using OfficeOpenXml; namespace Szmedi.RvKits.InfoManager.EAMTools { internal partial class EAMFacilityCodeViewModel : ObservableObject { readonly ActionEventHandler handler; [ObservableProperty] private string facilityCode; [ObservableProperty] private string prefix = "EAM"; [ObservableProperty] private string selectedFloor; [ObservableProperty] private string filePath; [ObservableProperty] private List tableNames; [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(SaveExcelFileCommand))] private string selectedTableName; public ObservableCollection Facilities { get; set; } = new ObservableCollection(); public ICollectionView FacilityCollection { get; set; } public List Floors { get; set; } = new List() { "B1","B2","B3","B4","B5","1F","2F","3F" }; [ObservableProperty] private string searchText; partial void OnSearchTextChanged(string value) { FacilityCollection.Refresh(); } [ObservableProperty] private FacilityInformation selectedFacility; public EAMFacilityCodeViewModel() { handler = new ActionEventHandler(); FacilityCollection = CollectionViewSource.GetDefaultView(Facilities); FacilityCollection.Filter = o => { if (string.IsNullOrEmpty(SearchText)) return true; if (o is FacilityInformation info) { return ((info.AssetName != null && info.AssetName.Contains(SearchText)) || (info.Name != null && info.Name.Contains(SearchText)) || (info.FacilityNumber != null && info.FacilityNumber.Contains(SearchText)) || (info.FunctionCode != null && info.FunctionCode.Contains(SearchText)) || (info.Location != null && info.Location.Contains(SearchText)) || (info.Location != null && info.LocationDetail.Contains(SearchText)) || (info.Floor != null && info.Floor.Contains(SearchText)) || (info.Comments != null && info.Comments.Contains(SearchText))); } return false; }; } [RelayCommand] private void GetSelectedFacility() { if (SelectedFacility != null) { if (SelectedFacility.FunctionCode != null) { FacilityCode = SelectedFacility.FunctionCode; } if (SelectedFacility.Location != null) { if (SelectedFacility.Location?.Contains("站厅") == true) { SelectedFloor = "B1"; } //if (SelectedFacility.Location.Contains("站台")) //{ // SelectedFloor = "B2"; //} } if (string.IsNullOrEmpty(SelectedFloor)) { if (SelectedFacility.Floor.Contains("站厅")) { SelectedFloor = "B1"; } //if (SelectedFacility.Floor.Contains("站台")) //{ // SelectedFloor = "B2"; //} } } } [RelayCommand] private void LocationSelectedFacility() { if (SelectedFacility == null) return; handler.Raise( uiapp => { try { var uidoc = uiapp.ActiveUIDocument; var doc = uidoc.Document; var collector = new Autodesk.Revit.DB.FilteredElementCollector(doc).WhereElementIsNotElementType() .Where(e => e.IsValidObject && e?.LookupParameter("标记")?.AsString()?.Contains(SelectedFacility.FunctionCode) == true) .Select(e => e.Id) .ToList(); if (collector.Count() > 0) { uidoc.ShowElements(collector); uidoc.Selection.SetElementIds(collector); } else { MessageBox.Show( "未找到对应编码的设备,请确认该设备已设置编码", "提示", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }); } [RelayCommand] private void OpenExcelFile() { if (string.IsNullOrEmpty(FilePath)) return; Process.Start("excel.exe", $"\"{FilePath}\""); } [RelayCommand] private void BrowserExcelFile() { var ofd = new OpenFileDialog(); ofd.Filter = "Excel文件|*.xlsx;*.xls"; if (ofd.ShowDialog() == true) { FilePath = ofd.FileName; var excelPackage = new ExcelPackage(new System.IO.FileInfo(FilePath)); TableNames = excelPackage.Workbook.Worksheets.Select(w => w.Name).ToList(); SelectedTableName = string.Empty; SelectedTableName = TableNames.FirstOrDefault(); } } public static string GetBindingPath(DataGridColumn column) { if (column is DataGridTextColumn textColumn && textColumn.Binding is Binding binding) return binding.Path.Path; // 其他列类型如 DataGridCheckBoxColumn 等类似处理 return null; } private bool CanSaveExcelFile => !string.IsNullOrEmpty(SelectedTableName); [RelayCommand(CanExecute = nameof(CanSaveExcelFile))] private void SaveExcelFile() { SaveFileDialog dialog = new SaveFileDialog { Filter = "Excel文件(*.xlsx)|*.xlsx;", FileName = "EAM设备编码信息.xlsx" }; if (dialog.ShowDialog() != true) { return; } FileInfo fi = new FileInfo(dialog.FileName); ExcelPackage package = Facilities .ToWorksheet(SelectedTableName) .WithConfiguration(cfg => cfg.WithColumnConfiguration(c => c.AutoFit())) .ToExcelPackage(); package.SaveAs(fi); MessageBoxResult result = MessageBox.Show("保存成功,是否打开导出的结果表?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { Process.Start(dialog.FileName); } } partial void OnSelectedTableNameChanged(string value) { if (string.IsNullOrEmpty(value)) { return; } int headerRowIndex = 1; var excelPackage = new ExcelPackage(new FileInfo(FilePath)); var worksheet = excelPackage.GetWorksheet(value); var isFirstCellEmpty = worksheet.IsCellEmpty(1, 1); if (isFirstCellEmpty) { // 使用第二行作为标题 headerRowIndex = 2; var tempSheet = excelPackage.AddWorksheet("TempSheet"); worksheet.Cells[ FromRow: headerRowIndex, FromCol: 1, ToRow: worksheet.Dimension.End.Row, ToCol: worksheet.Dimension.End.Column ] .Copy(tempSheet.Cells[ FromRow: 1, FromCol: 1, ToRow: worksheet.Dimension.End.Row - headerRowIndex, ToCol: worksheet.Dimension.End.Column ]); worksheet = tempSheet; } var collection = worksheet.ToList(configuration => configuration.SkipCastingErrors()); Facilities.Clear(); collection.ForEach(Facilities.Add); } [RelayCommand] private void AddToComponent() { var code = $"{Prefix}-{SelectedFloor}-{FacilityCode}"; handler.Raise(uiapp => { var doc = uiapp.ActiveUIDocument.Document; using (var t = new Autodesk.Revit.DB.Transaction(doc, "设置EAM编码")) { t.Start(); var sel = uiapp.ActiveUIDocument.Selection.GetElementIds(); if (sel.Count == 0) { var reference = uiapp.ActiveUIDocument.Selection .PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "请选择要编码的设备"); sel.Add(reference.ElementId); } foreach (var id in sel) { var e = doc.GetElement(id); if (e != null) { e.LookupParameter("标记")?.Set(code); } } t.Commit(); } if (SelectedFacility != null) { SelectedFacility.IsChecked = true; } }); } } }