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 dicfsColoumn = new Dictionary(); 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 = new List(); //将柱数据转成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 targetcdm = from d in cdmData where d.Level.Id.Equals(levels[i].Id) && d.TypeId.Equals(id) select d; //排序 List li = targetcdm.OrderByDescending(c => c.Center_Y).ThenBy(c => c.Center_X).ToList(); //var li = targetcdm.ToList(); //IEnumerable 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 dicFloors = new Dictionary(); 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 targetcdm = from d in cdmData where d.Level.Id.Equals(levels[i].Id) && d.TypeId.Equals(id) select d; //排序 //var li = targetcdm.ToList(); List 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 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("边长X(m)", typeof(double)); dt.Columns.Add("边长Y(m)", 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 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); } } } } }