xBIM 基础15 IFC导出Excel报表
IFC导出Excel空间报表文件
本篇将向您展示从IFC文件读取数据所需的一些概念。它使用IFC4接口,适用于IFC2x3和IFC4型号。要创建Excel文件,我们使用NPOI。在这个例子中你只需要 xBIM Essentials 组件。包含样本数据的所有代码均可在此处获得。
此示例的结果如下所示:
您将需要以下using
声明:
using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.Diagnostics; using System.IO; using System.Linq; using Xbim.Ifc; using Xbim.Ifc4.Interfaces;
主要功能如下:
//从模板初始化NPOI工作簿 var workbook = new XSSFWorkbook("template.xlsx"); var sheet = workbook.GetSheet("Spaces");//用单位创建漂亮的数字格式。 现实中需要更多的关心的是单位。
//我们只知道我们现在的模型有空间面积以立方米和空间体积为单位 //请注意从Revit导出的原始数据是错误的,因为数据量比应该大1000倍。 //在这个例子中,数据是使用xBIM修复的。 var areaFormat = workbook.CreateDataFormat(); var areaFormatId = areaFormat.GetFormat("# ##0.00 [$m²]"); var areaStyle = workbook.CreateCellStyle(); areaStyle.DataFormat = areaFormatId; var volumeFormat = workbook.CreateDataFormat(); var volumeFormatId = volumeFormat.GetFormat("# ##0.00 [$m³]"); var volumeStyle = workbook.CreateCellStyle(); volumeStyle.DataFormat = volumeFormatId; //打开IFC模型。 不会改变模型中的任何东西,所以我们可以把编辑器的信息保留下来。 using (var model = IfcStore.Open("SampleHouse.ifc")) { //获取模型中的所有空间. //需要 ToList() 方便使用 Foreach var spaces = model.Instances.OfType<IIfcSpace>().ToList(); //设置报表标题 sheet.GetRow(0).GetCell(0) .SetCellValue($"Space Report ({spaces.Count} spaces)"); foreach (var space in spaces) { //写报表数据 WriteSpaceRow(space, sheet, areaStyle, volumeStyle); } } //保存 报表 using (var stream = File.Create("spaces.xlsx")) { workbook.Write(stream); stream.Close(); } //打开保存的EXCEL 文件 Process.Start("spaces.xlsx");
此代码使用以下函数从IFC读取数据并为每个空间写入一行
private static void WriteSpaceRow(IIfcSpace space, ISheet sheet, ICellStyle areaStyle, ICellStyle volumeStyle) { var row = sheet.CreateRow(sheet.LastRowNum + 1); var name = space.Name; row.CreateCell(0).SetCellValue(name); var floor = GetFloor(space); row.CreateCell(1).SetCellValue(floor?.Name); var area = GetArea(space); if (area != null) { var cell = row.CreateCell(2); cell.CellStyle = areaStyle; // 如果来自属性而不是数量,那么僵不能保证它是数字 if (area.UnderlyingSystemType == typeof(double)) cell.SetCellValue((double)(area.Value)); else cell.SetCellValue(area.ToString()); } var volume = GetVolume(space); if (volume != null) { var cell = row.CreateCell(3); cell.CellStyle = volumeStyle; // 如果来自属性而不是数量,那么将不能保证它是数字 if (volume.UnderlyingSystemType == typeof(double)) cell.SetCellValue((double)(volume.Value)); else cell.SetCellValue(volume.ToString()); } }
要获得包含空间的楼层,您需要执行此操作:
private static IIfcBuildingStorey GetFloor(IIfcSpace space) { return //获取所有对象化的关系,这些关系将按此空间进行分解 space.Decomposes //选择分解的对象(这些对象可能是其他空间或建筑楼层) .Select(r => r.RelatingObject) //仅获取楼层 .OfType<IIfcBuildingStorey>() //获取第一个 .FirstOrDefault(); }
IFC包含数据基础结构,用于存储与产品及其类型相关的任意数据。这种基础设施相当复杂。存储数据的两种主要方式是数量或属性。数量是明确的,它们包含的值的类型,其中属性可以包含许多不同的数据类型作为值。对于面积和体积,如果定义了数量,则最好从数量中获取值
private static IIfcValue GetArea(IIfcProduct product) { //尝试先从数量中获取 var area = //获取可以定义属性和数量集的所有关系 product.IsDefinedBy //在所有属性和数量集之间搜索。 //您可能还希望按名称搜索特定数量 .SelectMany(r => r.RelatingPropertyDefinition.PropertySetDefinitions) //数量集合 .OfType<IIfcElementQuantity>() //从数量集获取所有数量 .SelectMany(qset => qset.Quantities) //我们只对面积感兴趣 .OfType<IIfcQuantityArea>() //我们将采取第一个。显然有一个以上的面积属性 //所以, 要检查的名称。但是,我们将保持它简单的这个例子。 .FirstOrDefault()? .AreaValue; if (area != null) return area; //从属性中获取值 return GetProperty(product, "Area"); } private static IIfcValue GetVolume(IIfcProduct product) { var volume = product.IsDefinedBy .SelectMany(r => r.RelatingPropertyDefinition.PropertySetDefinitions) .OfType<IIfcElementQuantity>() .SelectMany(qset => qset.Quantities) .OfType<IIfcQuantityVolume>() .FirstOrDefault()?.VolumeValue; if (volume != null) return volume; return GetProperty(product, "Volume"); }
更常见的属性在属性集中搜索
private static IIfcValue GetProperty(IIfcProduct product, string name) { return //获取可以定义属性和数量集的所有关系 product.IsDefinedBy //在所有属性和数量集之间搜索。您可能还希望在特定属性集中搜索 .SelectMany(r => r.RelatingPropertyDefinition.PropertySetDefinitions) //在这种情况下, 只考虑属性集。 .OfType<IIfcPropertySet>() //从所有属性集中获取所有属性 .SelectMany(pset => pset.HasProperties) //只允许考虑单个值属性。还有枚举属性, //表属性、引用属性、复杂属性和其他 .OfType<IIfcPropertySingleValue>() .Where(p => string.Equals(p.Name, name, System.StringComparison.OrdinalIgnoreCase) || p.Name.ToString().ToLower().Contains(name.ToLower())) .FirstOrDefault()?.NominalValue; }
成在管理,败在经验;嬴在选择,输在不学! 贵在坚持!
个人作品
BIMFace.SDK.NET
开源地址:https://gitee.com/NAlps/BIMFace.SDK
系列博客:https://www.cnblogs.com/SavionZhang/p/11424431.html
系列视频:https://www.cnblogs.com/SavionZhang/p/14258393.html
技术栈
1、Visual Studio、.NET Core/.NET、MVC、Web API、RESTful API、gRPC、SignalR、Java、Python
2、jQuery、Vue.js、Bootstrap、ElementUI
3、数据库:分库分表、读写分离、SQLServer、MySQL、PostgreSQL、Redis、MongoDB、ElasticSearch、达梦DM
4、架构:DDD、ABP、SpringBoot、jFinal
5、环境:跨平台、Windows、Linux、Nginx
6、移动App:Android、IOS、HarmonyOS、微信小程序、钉钉、uni-app、MAUI
分布式、高并发、云原生、微服务、Docker、CI/CD、DevOps、K8S;Dapr、RabbitMQ、Kafka、RPC、Elasticsearch。
欢迎关注作者头条号 张传宁IT讲堂,获取更多IT文章、视频等优质内容。
出处:www.cnblogs.com/SavionZhang
作者:张传宁 技术顾问、培训讲师、微软MCP、系统架构设计师、系统集成项目管理工程师、科技部创新工程师。
专注于企业级通用开发平台、工作流引擎、自动化项目(代码)生成器、SOA 、DDD、 云原生(Docker、微服务、DevOps、CI/CD);PDF、CAD、BIM 审图等研究与应用。
多次参与电子政务、图书教育、生产制造等企业级大型项目研发与管理工作。
熟悉中小企业软件开发过程:可行调研、需求分析、架构设计、编码测试、实施部署、项目管理。通过技术与管理帮助中小企业实现互联网转型升级全流程解决方案。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如有问题,可以通过邮件905442693@qq.com联系。共同交流、互相学习。
如果您觉得文章对您有帮助,请点击文章右下角【推荐】。您的鼓励是作者持续创作的最大动力!