Files
CDMUtility/CivilModelCreator/CmdExportCDMDataToExcel.cs
2026-02-23 14:35:54 +08:00

489 lines
22 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB.Structure;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.Data;
namespace CivilModelCreator
{
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class CmdExportCDMDataToExcel : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Autodesk.Revit.ApplicationServices.Application app = commandData.Application.Application;
Document doc = commandData.Application.ActiveUIDocument.Document;
VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog
{
Multiselect = false
};
dialog.ShowDialog();
if (dialog.SelectedPath == null)
{
return Result.Cancelled;
}
string path = dialog.SelectedPath;
var StColumns = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).OfClass(typeof(FamilyInstance)).ToElements();
var floors = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).OfClass(typeof(Floor)).ToElements();
var beams = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralFraming).OfClass(typeof(FamilyInstance)).ToElements();
var levels = new FilteredElementCollector(doc).OfClass(typeof(Level)).ToElements();
#region
Dictionary<ElementId, string> dicfsColoumn = new Dictionary<ElementId, string>();
int num = 1;
//查找所有具有实例的柱子类型及赋予编码
for (int i = 0; i < StColumns.Count(); i++)
{
ElementId fiId = ((FamilyInstance)StColumns[i]).Symbol.Id;
try
{
dicfsColoumn.Add(fiId, string.Format("0{0}", num));
num += 1;
}
catch (Exception)
{
continue;
}
}
List<CDMData> cdmData = new List<CDMData>();
//将柱数据转成cdm数据
foreach (FamilyInstance column in StColumns)
{
//cdm.SymbolId = column.GetTypeId();
//坐标
XYZ p1 = column.GetTotalTransform().Origin;
CDMData cdm = new CDMData
{
TypeId = column.Symbol.Id,
Center_X = p1.X * 304.8 / 1000,
Center_Y = p1.Y * 304.8 / 1000,
HcdmClass = "A2001",
Level = (Level)doc.GetElement(column.LevelId),
Name = column.Symbol.Family.Name + "" + column.Symbol.Name,
Category = "柱",
};
dicfsColoumn.TryGetValue(column.Symbol.Id, out cdm.CategoryId);
//底部标高名称
string baselevelname = column.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).AsValueString();
//顶部标高名称
string toplevelname = column.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).AsValueString();
//var value = dict.Where(q => q.Key == column.Symbol.Id).Select(q => q.Value).FirstOrDefault();
//cdm.HcdmNumber = String.Format("{0}-{1}", value.ToString(), baselevelname);
foreach (Level lev in levels)
{
//以深度去布置柱子,底标高和顶标高相反
if (lev.Name == baselevelname)
{
//底部偏移
double baseoffest = column.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).AsDouble();
cdm.BaseLevel = UnitUtils.ConvertFromInternalUnits(lev.Elevation + baseoffest, DisplayUnitType.DUT_METERS);
//md.BaseLevel = lev.Elevation * 304.8 / 1000 + baseof;
}
if (lev.Name == toplevelname)
{
//顶部偏移
double topoffest = column.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).AsDouble();
cdm.TopLevel = UnitUtils.ConvertFromInternalUnits(lev.Elevation + topoffest, DisplayUnitType.DUT_METERS);
}
}
double b = 0;
double h = 0;
try
{
b = column.Symbol.LookupParameter("b").AsDouble();
h = column.Symbol.LookupParameter("h").AsDouble();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
cdm.Length = UnitUtils.ConvertFromInternalUnits(b, DisplayUnitType.DUT_METERS);
cdm.Width = UnitUtils.ConvertFromInternalUnits(h, DisplayUnitType.DUT_METERS);
cdmData.Add(cdm);
//md.Length=from Parameter para in fi.Parameters
// where para.Definition.Name=="b"
// select
//md.Length=fi.get_Parameter()
}
//层构件编号
for (int i = 0; i < levels.Count(); i++)
{
for (int j = 0; j < dicfsColoumn.Count; j++)
{
ElementId id = dicfsColoumn.ElementAt(j).Key;
//归类cdm中同标高同类型
IEnumerable<CDMData> targetcdm = from d in cdmData
where d.Level.Id.Equals(levels[i].Id) && d.TypeId.Equals(id)
select d;
//排序
List<CDMData> li = targetcdm.OrderByDescending(c => c.Center_Y).ThenBy(c => c.Center_X).ToList();
//var li = targetcdm.ToList();
//IEnumerable<CDMData> enuCdm = from cdm in targetcdm
// orderby cdm.Center_Y
// select cdm;
//li.Sort();
//while (itr.MoveNext)
//{
// Element e = (Element)itr.Current;
//}
for (int k = 0; k < li.ToList().Count; k++)
{
if (k > 8)
{
li[k].Code = string.Format("0{0}", k + 1);
}
else
{
li[k].Code = string.Format("00{0}", k + 1);
}
}
}
}
#endregion
#region
Dictionary<ElementId, string> dicFloors = new Dictionary<ElementId, string>();
int num1 = 1;
for (int i = 0; i < floors.Count; i++)
{
ElementId flId = floors[i].GetTypeId();
try
{
dicFloors.Add(flId, string.Format("0{0}", num1));
num1 += 1;
}
catch (Exception)
{
continue;
}
}
foreach (Floor floor in floors)
{
View3D v = (View3D)doc.ActiveView;
if (v == null)
{
System.Windows.MessageBox.Show("请使用三维视图");
}
XYZ max = floor.get_BoundingBox(v).Max;
XYZ min = floor.get_BoundingBox(v).Min;
XYZ p = (max + min) / 2;
CDMData cdm = new CDMData
{
Level = (Level)doc.GetElement(floor.LevelId),
TypeId = floor.FloorType.Id,
HcdmClass = "A2002",
Center_X = p.X * 304.8 / 1000,
Center_Y = p.Y * 304.8 / 1000,
Length = UnitUtils.ConvertFromInternalUnits(max.X - min.X, DisplayUnitType.DUT_METERS),
Width = UnitUtils.ConvertFromInternalUnits(max.Y - min.Y, DisplayUnitType.DUT_METERS),
BaseLevel = Convert.ToDouble(floor.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_BOTTOM).AsValueString()) / 1000,
TopLevel = Convert.ToDouble(floor.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_TOP).AsValueString()) / 1000,
Name = floor.FloorType.FamilyName + "" + floor.Name,
Category = "板",
};
dicFloors.TryGetValue(floor.FloorType.Id, out cdm.CategoryId);
cdmData.Add(cdm);
}
for (int i = 0; i < levels.Count(); i++)
{
for (int j = 0; j < dicFloors.Count; j++)
{
ElementId id = dicFloors.ElementAt(j).Key;
//归类cdm中同标高同类型
IEnumerable<CDMData> targetcdm = from d in cdmData
where d.Level.Id.Equals(levels[i].Id) && d.TypeId.Equals(id)
select d;
//排序
//var li = targetcdm.ToList();
List<CDMData> li = targetcdm.OrderByDescending(c => c.Center_Y).ThenBy(c => c.Center_X).ToList();
for (int k = 0; k < li.Count; k++)
{
if (k > 8)
{
li[k].Code = string.Format("0{0}", k + 1);
}
else
{
li[k].Code = string.Format("00{0}", k + 1);
}
}
}
}
#endregion
foreach (FamilyInstance beam in beams)
{
CDMData cdm = new CDMData();
}
cdmData = cdmData.OrderBy(c => c.CategoryId).ThenBy(c => c.LevelName).ThenBy(c => c.Code).ToList();
//ExportToSingleExcel(path, cdmData);
DataTable dt = WriteToDataTable(cdmData);
ExportToExcel(path, dt);
return Result.Succeeded;
}
public DataTable WriteToDataTable(List<CDMData> cdms)
{
DataTable dt = new DataTable();
dt.Columns.Add("构件分类", typeof(string));
dt.Columns.Add("族类型", typeof(string));
dt.Columns.Add("编号", typeof(string));
dt.Columns.Add("底标高m", typeof(double));
dt.Columns.Add("中心X", typeof(double));
dt.Columns.Add("中心Y", typeof(double));
dt.Columns.Add("边长Xm", typeof(double));
dt.Columns.Add("边长Ym", typeof(double));
dt.Columns.Add("顶标高m", typeof(double));
foreach (var cdm in cdms)
{
DataRow dr = dt.NewRow();
dr[0] = cdm.HcdmClass;
dr[1] = cdm.Name;
dr[2] = cdm.HcdmNumber;
dr[3] = cdm.BaseLevel;
dr[4] = cdm.Center_X;
dr[5] = cdm.Center_Y;
dr[6] = cdm.Length;
dr[7] = cdm.Width;
//dr[7] = UnitUtils.ConvertFromInternalUnits(h, DisplayUnitType.DUT_METERS);
dr[8] = cdm.TopLevel;
dt.Rows.Add(dr);
}
return dt;
}
static void ExportToSingleExcel(string path, List<CDMData> cdms)
{
foreach (CDMData cdm in cdms)
{
XSSFWorkbook workbook = new XSSFWorkbook();
ISheet firstSheet = workbook.CreateSheet("CDM数据表");
#region
firstSheet.CreateRow(0);
firstSheet.GetRow(0).CreateCell(0);
firstSheet.GetRow(0).CreateCell(1);
firstSheet.GetRow(0).CreateCell(2);
firstSheet.GetRow(0).GetCell(0).SetCellValue("HcdmClass");
firstSheet.GetRow(0).GetCell(1).SetCellValue(cdm.Category + "CDM专用标准");
firstSheet.GetRow(0).GetCell(2).SetCellValue(cdm.HcdmClass);
firstSheet.CreateRow(1);
firstSheet.GetRow(1).CreateCell(0);
firstSheet.GetRow(1).CreateCell(1);
firstSheet.GetRow(1).GetCell(0).SetCellValue("构件名称");
firstSheet.GetRow(1).GetCell(1).SetCellValue(cdm.Category);
firstSheet.CreateRow(2);
firstSheet.GetRow(2).CreateCell(0);
firstSheet.GetRow(2).CreateCell(1);
firstSheet.GetRow(2).CreateCell(2);
firstSheet.GetRow(2).GetCell(0).SetCellValue("HcdmClass");
firstSheet.GetRow(2).GetCell(1).SetCellValue("XXXXX(自动生成)");
firstSheet.GetRow(2).GetCell(2).SetCellValue(cdm.HcdmNumber);
firstSheet.CreateRow(4);
firstSheet.GetRow(4).CreateCell(0);
firstSheet.GetRow(4).CreateCell(1);
firstSheet.GetRow(4).CreateCell(2);
firstSheet.GetRow(4).CreateCell(3);
firstSheet.GetRow(4).CreateCell(4);
firstSheet.GetRow(4).GetCell(0).SetCellValue("字段编码");
firstSheet.GetRow(4).GetCell(1).SetCellValue("字段名称");
firstSheet.GetRow(4).GetCell(2).SetCellValue("单位");
firstSheet.GetRow(4).GetCell(3).SetCellValue("备注");
firstSheet.GetRow(4).GetCell(4).SetCellValue("字段值");
firstSheet.CreateRow(5);
firstSheet.GetRow(5).CreateCell(0);
firstSheet.GetRow(5).CreateCell(1);
firstSheet.GetRow(5).GetCell(0).SetCellValue("101");
firstSheet.GetRow(5).GetCell(1).SetCellValue("编号(自定义)");
firstSheet.CreateRow(6);
firstSheet.GetRow(6).CreateCell(0);
firstSheet.GetRow(6).CreateCell(1);
firstSheet.GetRow(6).CreateCell(2);
firstSheet.GetRow(6).CreateCell(4);
firstSheet.GetRow(6).GetCell(0).SetCellValue("102");
firstSheet.GetRow(6).GetCell(1).SetCellValue(cdm.Category + "底标高");
firstSheet.GetRow(6).GetCell(2).SetCellValue("m");
firstSheet.GetRow(6).GetCell(4).SetCellValue(Math.Round(cdm.BaseLevel, 2, MidpointRounding.AwayFromZero));
firstSheet.CreateRow(7);
firstSheet.GetRow(7).CreateCell(0);
firstSheet.GetRow(7).CreateCell(1);
firstSheet.GetRow(7).CreateCell(2);
firstSheet.GetRow(7).CreateCell(4);
firstSheet.GetRow(7).GetCell(0).SetCellValue("103");
firstSheet.GetRow(7).GetCell(1).SetCellValue(cdm.Category + "中心点坐标X");
firstSheet.GetRow(7).GetCell(2).SetCellValue("m");
firstSheet.GetRow(7).GetCell(4).SetCellValue(Math.Round(cdm.Center_X, 2, MidpointRounding.AwayFromZero));
firstSheet.CreateRow(8);
firstSheet.GetRow(8).CreateCell(0);
firstSheet.GetRow(8).CreateCell(1);
firstSheet.GetRow(8).CreateCell(2);
firstSheet.GetRow(8).CreateCell(4);
firstSheet.GetRow(8).GetCell(0).SetCellValue("104");
firstSheet.GetRow(8).GetCell(1).SetCellValue(cdm.Category + "中心点坐标Y");
firstSheet.GetRow(8).GetCell(2).SetCellValue("m");
firstSheet.GetRow(8).GetCell(4).SetCellValue(Math.Round(cdm.Center_Y, MidpointRounding.AwayFromZero));
firstSheet.CreateRow(9);
firstSheet.GetRow(9).CreateCell(0);
firstSheet.GetRow(9).CreateCell(1);
firstSheet.GetRow(9).CreateCell(2);
firstSheet.GetRow(9).CreateCell(4);
firstSheet.GetRow(9).GetCell(0).SetCellValue("105");
firstSheet.GetRow(9).GetCell(1).SetCellValue(cdm.Category + "边长X");
firstSheet.GetRow(9).GetCell(2).SetCellValue("m");
firstSheet.GetRow(9).GetCell(4).SetCellValue(Math.Round(cdm.Length, 2, MidpointRounding.AwayFromZero));
firstSheet.CreateRow(10);
firstSheet.GetRow(10).CreateCell(0);
firstSheet.GetRow(10).CreateCell(1);
firstSheet.GetRow(10).CreateCell(2);
firstSheet.GetRow(10).CreateCell(4);
firstSheet.GetRow(10).GetCell(0).SetCellValue("106");
firstSheet.GetRow(10).GetCell(1).SetCellValue(cdm.Category + "边长Y");
firstSheet.GetRow(10).GetCell(2).SetCellValue("m");
firstSheet.GetRow(10).GetCell(4).SetCellValue(Math.Round(cdm.Width, 2, MidpointRounding.AwayFromZero));
firstSheet.CreateRow(11);
firstSheet.GetRow(11).CreateCell(0);
firstSheet.GetRow(11).CreateCell(1);
firstSheet.GetRow(11).CreateCell(2);
firstSheet.GetRow(11).CreateCell(4);
firstSheet.GetRow(11).GetCell(0).SetCellValue("107");
firstSheet.GetRow(11).GetCell(1).SetCellValue(cdm.Category + "顶标高");
firstSheet.GetRow(11).GetCell(2).SetCellValue("m");
firstSheet.GetRow(11).GetCell(4).SetCellValue(Math.Round(cdm.TopLevel, 2, MidpointRounding.AwayFromZero));
firstSheet.CreateRow(12);
firstSheet.GetRow(12).CreateCell(0);
firstSheet.GetRow(12).CreateCell(1);
firstSheet.GetRow(12).CreateCell(2);
firstSheet.GetRow(12).CreateCell(4);
firstSheet.GetRow(12).GetCell(0).SetCellValue("108");
firstSheet.GetRow(12).GetCell(1).SetCellValue(cdm.Category + "身材料");
firstSheet.GetRow(12).GetCell(2).SetCellValue("混凝土、砖、其他");
firstSheet.GetRow(12).GetCell(4).SetCellValue(cdm.Material);
firstSheet.CreateRow(13);
firstSheet.GetRow(13).CreateCell(0);
firstSheet.GetRow(13).CreateCell(1);
firstSheet.GetRow(13).CreateCell(2);
firstSheet.GetRow(13).CreateCell(4);
firstSheet.GetRow(13).GetCell(0).SetCellValue("109");
firstSheet.GetRow(13).GetCell(1).SetCellValue(cdm.Category + "材料强度(标准值)");
firstSheet.GetRow(13).GetCell(2).SetCellValue("MPa");
firstSheet.GetRow(13).GetCell(4).SetCellValue(cdm.Strength);
firstSheet.CreateRow(14);
firstSheet.GetRow(14).CreateCell(0);
firstSheet.GetRow(14).CreateCell(1);
firstSheet.GetRow(14).CreateCell(2);
firstSheet.GetRow(14).CreateCell(4);
firstSheet.GetRow(14).GetCell(0).SetCellValue("110");
firstSheet.GetRow(14).GetCell(1).SetCellValue("设计负责人");
firstSheet.GetRow(14).GetCell(2).SetCellValue("姓名");
firstSheet.GetRow(14).GetCell(4).SetCellValue(cdm.Designer);
firstSheet.CreateRow(15);
firstSheet.GetRow(15).CreateCell(0);
firstSheet.GetRow(15).CreateCell(1);
//firstSheet.GetRow(15).CreateCell(2);
firstSheet.GetRow(15).CreateCell(4);
firstSheet.GetRow(15).GetCell(0).SetCellValue("111");
firstSheet.GetRow(15).GetCell(1).SetCellValue("身份证");
//firstSheet.GetRow(15).GetCell(2).SetCellValue("");
firstSheet.GetRow(15).GetCell(4).SetCellValue(cdm.Iden);
firstSheet.AutoSizeColumn(0);
firstSheet.AutoSizeColumn(1);
firstSheet.AutoSizeColumn(2);
firstSheet.AutoSizeColumn(3);
firstSheet.AutoSizeColumn(4);
#endregion
using (FileStream excelStream = File.Create(path + "\\" + cdm.HcdmClass + "-" + cdm.HcdmNumber + ".xlsx"))
{
workbook.Write(excelStream);
}
}
}
static void ExportToExcel(string path, DataTable dt)
{
string exportedExcelFullName = path + "\\" + DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".xlsx";
if (dt != null && dt.Rows.Count > 0)
{
XSSFWorkbook workBook = new XSSFWorkbook();
ISheet firstSheet = workBook.CreateSheet("CDM数据表");
IRow headerRow = firstSheet.CreateRow(0);
for (int i = 0; i < dt.Columns.Count; i++)
{
ICell headerCell = headerRow.CreateCell(i);
headerCell.SetCellValue(dt.Columns[i].ColumnName?.ToString());
}
for (int i = 0; i < dt.Rows.Count; i++)
{
IRow dataRow = firstSheet.CreateRow(i + 1);
for (int j = 0; j < dt.Columns.Count; j++)
{
ICell dataCell = dataRow.CreateCell(j);
//dataCell.SetCellValue(dt.Rows[i][j]?.ToString());
var str = dt.Rows[i][j]?.ToString();
double value = 0.0;
//能否转换为数字
if (double.TryParse(str, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out value))
{
dataCell.SetCellValue(Math.Round(value, 2, MidpointRounding.AwayFromZero));
}
else
{
dataCell.SetCellValue(dt.Rows[i][j]?.ToString());
}
}
}
for (int i = 0; i < dt.Columns.Count; i++)
{
firstSheet.AutoSizeColumn(i);
}
using (FileStream excelStream = File.Create(exportedExcelFullName))
{
workBook.Write(excelStream);
}
}
}
}
}