Files
SzmediTools/Szmedi.RvKits/FamilyTools/QueryExportViewModel.cs
2025-09-16 16:06:41 +08:00

363 lines
13 KiB
C#

using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Microsoft.Win32;
using Szmedi.RvKits.Assists;
namespace Szmedi.RvKits.FamilyTools
{
public partial class QueryExportViewModel : ObservableObject
{
public QueryExportViewModel(UIDocument uidoc)
{
Document = uidoc.Document;
ViewSchedules = Document.OfCollector()
.OfClass(typeof(ViewSchedule))
.OfCategory(BuiltInCategory.OST_Schedules)
.Cast<ViewSchedule>()
.ToList();
this.uidoc = uidoc;
}
public ObservableCollection<string> ExportProps { get; set; } = [];
[ObservableProperty]
private Comparison comparisonType = Comparison.Contains;
[ObservableProperty]
private string outputFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), $"查询结果{DateTime.Now:yyyy-MM-dd}");
[ObservableProperty]
private List<ViewSchedule> viewSchedules;
[ObservableProperty]
private Document document;
[ObservableProperty]
private string propertyName = Properties.Settings.Default.QueryExportPropName;
partial void OnPropertyNameChanged(string oldValue, string newValue)
{
if (oldValue == newValue)
{
return;
}
Properties.Settings.Default.QueryExportPropName = newValue;
Properties.Settings.Default.Save();
}
[ObservableProperty]
private string propertyValueToCompare = Properties.Settings.Default.QueryExportPropValueCompare;
private readonly UIDocument uidoc;
partial void OnPropertyValueToCompareChanged(string oldValue, string newValue)
{
if (oldValue == newValue)
{
return;
}
Properties.Settings.Default.QueryExportPropValueCompare = newValue;
Properties.Settings.Default.Save();
}
[RelayCommand]
private void Add(string prop)
{
if (!string.IsNullOrEmpty(prop) && !ExportProps.Contains(prop))
{
ExportProps.Add(prop);
}
}
[RelayCommand]
private void Remove(string prop)
{
if (ExportProps.Contains(prop))
{
ExportProps.Remove(prop);
}
}
[RelayCommand]
private void ExportSchedule(IList schedules)
{
if (schedules.Count == 0)
{
MessageBox.Show("请选择至少一个明细表!", "错误");
return;
}
FolderBrowserDialog browserWindow = new();
if (browserWindow.ShowDialog())
{
var selectedPath = browserWindow.SelectedPath;
if (!Directory.Exists(selectedPath))
{
MessageBox.Show("文件目录不存在!", "警告");
return;
}
var path = Path.Combine(selectedPath, $"{Document.Title}.xlsx");
EPPlusHelpers.WriteExcel(
path,
m =>
{
foreach (ViewSchedule viewSchedule in schedules)
{
if (!viewSchedule.CanHaveTypeAssigned())
{
continue;
}
var sheet = m.Workbook.Worksheets.Add(viewSchedule.Name);
var td = viewSchedule.GetTableData();
var tdd = td.GetSectionData(SectionType.Body);
var c = tdd.NumberOfColumns;
var r = tdd.NumberOfRows;
for (var i = 0; i < r; i++)
{
for (var j = 0; j < c; j++)
{
sheet.Cells[i + 1, j + 1].Value = viewSchedule.GetCellText(SectionType.Body, i, j);
}
}
//EPPlusHelpers.SetStyle(sheet, 1, sheet.Dimension.Rows, 1, sheet.Dimension.Columns);
}
}
);
var result = MessageBox.Show("是否打开导出的文件", "导出完成", MessageBoxButton.OKCancel, MessageBoxImage.Information);
if (result == MessageBoxResult.OK)
{
Process.Start(path);
}
}
}
[RelayCommand]
private void SelectElements()
{
var instances = QueryElements(Document);
uidoc.Selection.SetElementIds(instances.Select(e => e.Id).ToList());
}
private bool CanQueryCurrent => Document != null && !Document.IsFamilyDocument;
[RelayCommand(CanExecute = nameof(CanQueryCurrent))]
private void QueryExport()
{
if (!Directory.Exists(OutputFolder))
{
Directory.CreateDirectory(OutputFolder);
}
if (QueryExportFormDocument(Document))
{
var result = MessageBox.Show("是否打开导出的文件?", "导出完成", MessageBoxButton.YesNo, MessageBoxImage.Information);
if (result == MessageBoxResult.Yes)
{
Process.Start(Path.Combine(OutputFolder, $"{Document.Title}.csv"));
}
}
//SaveFileDialog browserWindow = new()
//{
// Filter = "文本文件(*.csv)|*.csv",
// Title = "导出到csv",
// FileName = $"{doc.Title}.csv"
//};
//if (browserWindow.ShowDialog() == true)
//{
// if (!Directory.Exists(OutputFolder))
// {
// Directory.CreateDirectory(OutputFolder);
// }
// if (QueryExportFormDocument(doc))
// {
// var result = MessageBox.Show("是否打开导出的文件?", "导出完成", MessageBoxButton.YesNo, MessageBoxImage.Information);
// if (result == MessageBoxResult.Yes)
// {
// Process.Start(browserWindow.FileName);
// }
// }
//}
}
[RelayCommand]
private void MultiQueryExport()
{
OpenFileDialog dialog =
new()
{
Title = "选择Revit项目文件",
Filter = "Revit项目文件(*.rvt)|*.rvt",
Multiselect = true
};
if (dialog.ShowDialog() == true)
{
if (!Directory.Exists(OutputFolder))
{
Directory.CreateDirectory(OutputFolder);
}
//Func<string, string, Comparison, bool> func = ComparisonResult;
foreach (var item in dialog.FileNames)
{
var doc = Document.Application.OpenDocumentFile(item);
QueryExportFormDocument(doc);
doc.Close(false);
}
var result = MessageBox.Show("是否打开导出的目录?", "导出完成", MessageBoxButton.YesNo, MessageBoxImage.Information);
if (result == MessageBoxResult.Yes)
{
Process.Start(new ProcessStartInfo(OutputFolder) { UseShellExecute = true });
}
//MessageBox.Show("导出完成", "提示");
}
}
/// <summary>
/// 选择输出目录
/// </summary>
/// <param name="window"></param>
[RelayCommand]
private void SelectOutputFolder(Window window)
{
FolderBrowserDialog dialog = new();
if (dialog.ShowDialog(window))
{
OutputFolder = dialog.SelectedPath;
}
}
private bool QueryExportFormDocument(Document doc)
{
var instances = QueryElements(doc);
var sb = new StringBuilder();
//根据导出的属性数量,设置列表表头
if (ExportProps.Count == 0)
{
sb.AppendLine("元素Id,族,类型,");
}
else
{
sb.Append("元素Id,族,类型,");
foreach (var str in ExportProps)
{
sb.Append($"{str},");
}
sb.AppendLine();
}
foreach (var instance in instances)
{
var elem = doc.GetElement(instance.GetTypeId());
var familyName = elem is ElementType elementType ? elementType.FamilyName : elem == null ? instance.Name : elem.Name;
if (ExportProps.Count == 0)
{
sb.AppendLine($"{instance.Id},{familyName},{instance.Name},");
}
else
{
sb.Append($"{instance.Id},{familyName},{instance.Name},");
foreach (var str in ExportProps)
{
var param = instance.GetParameters(str).FirstOrDefault();
if (param != null)
{
sb.Append($"{param.AsString()},");
}
else
{
sb.Append(",");
}
}
sb.AppendLine();
}
}
if (!instances.Any())
{
MessageBox.Show($"项目文件 {doc.Title} 未查询到元素", "提示");
return false;
}
var filePath = Path.Combine(OutputFolder, $"{doc.Title}.csv");
File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8);
return true;
}
private IEnumerable<Element> QueryElements(Document doc)
{
var allInstances = doc.OfParentModelCollector();
IEnumerable<Element> instances = null;
//当不填写其中的匹配属性和属性值时,查询整个模型所有实例
if (string.IsNullOrEmpty(PropertyName) || string.IsNullOrEmpty(PropertyValueToCompare))
{
instances = allInstances;
}
else
{
switch (ComparisonType)
{
case Comparison.Equals:
instances = allInstances.Where(i =>
{
var str = GetPropertyString(i);
return !string.IsNullOrEmpty(str) && str == PropertyValueToCompare;
});
break;
case Comparison.Contains:
instances = allInstances.Where(i =>
{
var str = GetPropertyString(i);
return !string.IsNullOrEmpty(str) && str.Contains(PropertyValueToCompare);
});
break;
case Comparison.NoContains:
instances = allInstances.Where(i =>
{
var str = GetPropertyString(i);
return !string.IsNullOrEmpty(str) && !str.Contains(PropertyValueToCompare);
});
break;
case Comparison.StartWith:
instances = allInstances.Where(i =>
{
var str = GetPropertyString(i);
return !string.IsNullOrEmpty(str) && str.StartsWith(PropertyValueToCompare);
});
break;
case Comparison.EndWith:
instances = allInstances.Where(i =>
{
var str = GetPropertyString(i);
return !string.IsNullOrEmpty(str) && str.EndsWith(PropertyValueToCompare);
});
break;
default:
break;
}
}
return instances;
}
private string GetPropertyString(Element i)
{
var doc = i.Document;
if (PropertyName == "族")
{
var elem = doc.GetElement(i.GetTypeId());
return elem is ElementType elementType ? elementType.FamilyName : elem?.Name;
}
if (PropertyName == "类型")
{
return i.Name;
}
var param = i.GetParameters(PropertyName).FirstOrDefault();
return param != null && param.StorageType == StorageType.String ? param.AsString() : null;
}
}
}