363 lines
13 KiB
C#
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|