← 返回 Skills 市场
Ifc To Excel
作者
datadrivenconstruction
· GitHub ↗
· v2.0.0
1220
总下载
0
收藏
2
当前安装
2
版本数
在 OpenClaw 中安装
/install ifc-to-excel
功能描述
Convert IFC files (2x3, 4x1, 4x3) to Excel databases using IfcExporter CLI. Extract BIM data, properties, and geometry without proprietary software.
使用说明 (SKILL.md)
\r \r
IFC to Excel Conversion\r
\r
Business Case\r
\r
Problem Statement\r
IFC (Industry Foundation Classes) is the open BIM standard, but:\r
- Reading IFC requires specialized software\r
- Property extraction needs programming knowledge\r
- Batch processing is manual and time-consuming\r
- Integration with analytics tools is complex\r \r
Solution\r
IfcExporter.exe converts IFC files to structured Excel databases, making BIM data accessible for analysis, validation, and reporting.\r \r
Business Value\r
- Open standard - Process any IFC file (2x3, 4x, 4.3)\r
- No licenses - Works offline without BIM software\r
- Data extraction - All properties, quantities, materials\r
- 3D geometry - Export to Collada DAE format\r
- Pipeline ready - Integrate with ETL workflows\r \r
Technical Implementation\r
\r
CLI Syntax\r
IfcExporter.exe \x3Cinput_ifc> [options]\r
```\r
\r
### Supported IFC Versions\r
| Version | Schema | Description |\r
|---------|--------|-------------|\r
| IFC2x3 | MVD | Most common exchange format |\r
| IFC4 | ADD1 | Enhanced properties |\r
| IFC4x1 | Alignment | Infrastructure support |\r
| IFC4x3 | Latest | Full infrastructure |\r
\r
### Output Formats\r
| Output | Description |\r
|--------|-------------|\r
| `.xlsx` | Excel database with elements and properties |\r
| `.dae` | Collada 3D geometry with matching IDs |\r
\r
### Options\r
| Option | Description |\r
|--------|-------------|\r
| `bbox` | Include element bounding boxes |\r
| `-no-xlsx` | Skip Excel export |\r
| `-no-collada` | Skip 3D geometry export |\r
\r
### Examples\r
\r
```bash\r
# Basic conversion (XLSX + DAE)\r
IfcExporter.exe "C:\Models\Building.ifc"\r
\r
# With bounding boxes\r
IfcExporter.exe "C:\Models\Building.ifc" bbox\r
\r
# Excel only (no 3D geometry)\r
IfcExporter.exe "C:\Models\Building.ifc" -no-collada\r
\r
# Batch processing\r
for /R "C:\IFC_Models" %f in (*.ifc) do IfcExporter.exe "%f" bbox\r
```\r
\r
### Python Integration\r
\r
```python\r
import subprocess\r
import pandas as pd\r
from pathlib import Path\r
from typing import List, Optional, Dict, Any, Set\r
from dataclasses import dataclass, field\r
from enum import Enum\r
import json\r
\r
\r
class IFCVersion(Enum):\r
"""IFC schema versions."""\r
IFC2X3 = "IFC2X3"\r
IFC4 = "IFC4"\r
IFC4X1 = "IFC4X1"\r
IFC4X3 = "IFC4X3"\r
\r
\r
class IFCEntityType(Enum):\r
"""Common IFC entity types."""\r
IFCWALL = "IfcWall"\r
IFCWALLSTANDARDCASE = "IfcWallStandardCase"\r
IFCSLAB = "IfcSlab"\r
IFCCOLUMN = "IfcColumn"\r
IFCBEAM = "IfcBeam"\r
IFCDOOR = "IfcDoor"\r
IFCWINDOW = "IfcWindow"\r
IFCROOF = "IfcRoof"\r
IFCSTAIR = "IfcStair"\r
IFCRAILING = "IfcRailing"\r
IFCFURNISHINGELEMENT = "IfcFurnishingElement"\r
IFCSPACE = "IfcSpace"\r
IFCBUILDINGSTOREY = "IfcBuildingStorey"\r
IFCBUILDING = "IfcBuilding"\r
IFCSITE = "IfcSite"\r
\r
\r
@dataclass\r
class IFCElement:\r
"""Represents an IFC element."""\r
global_id: str\r
ifc_type: str\r
name: str\r
description: Optional[str]\r
object_type: Optional[str]\r
level: Optional[str]\r
\r
# Quantities\r
area: Optional[float] = None\r
volume: Optional[float] = None\r
length: Optional[float] = None\r
height: Optional[float] = None\r
width: Optional[float] = None\r
\r
# Bounding box (if exported)\r
bbox_min_x: Optional[float] = None\r
bbox_min_y: Optional[float] = None\r
bbox_min_z: Optional[float] = None\r
bbox_max_x: Optional[float] = None\r
bbox_max_y: Optional[float] = None\r
bbox_max_z: Optional[float] = None\r
\r
# Properties\r
properties: Dict[str, Any] = field(default_factory=dict)\r
materials: List[str] = field(default_factory=list)\r
\r
\r
@dataclass\r
class IFCProperty:\r
"""Represents an IFC property."""\r
pset_name: str\r
property_name: str\r
value: Any\r
value_type: str\r
\r
\r
@dataclass\r
class IFCMaterial:\r
"""Represents an IFC material."""\r
name: str\r
category: Optional[str]\r
thickness: Optional[float]\r
layer_position: Optional[int]\r
\r
\r
class IFCExporter:\r
"""IFC to Excel converter using DDC IfcExporter CLI."""\r
\r
def __init__(self, exporter_path: str = "IfcExporter.exe"):\r
self.exporter = Path(exporter_path)\r
if not self.exporter.exists():\r
raise FileNotFoundError(f"IfcExporter not found: {exporter_path}")\r
\r
def convert(self, ifc_file: str,\r
include_bbox: bool = True,\r
export_xlsx: bool = True,\r
export_collada: bool = True) -> Path:\r
"""Convert IFC file to Excel."""\r
ifc_path = Path(ifc_file)\r
if not ifc_path.exists():\r
raise FileNotFoundError(f"IFC file not found: {ifc_file}")\r
\r
cmd = [str(self.exporter), str(ifc_path)]\r
\r
if include_bbox:\r
cmd.append("bbox")\r
if not export_xlsx:\r
cmd.append("-no-xlsx")\r
if not export_collada:\r
cmd.append("-no-collada")\r
\r
result = subprocess.run(cmd, capture_output=True, text=True)\r
\r
if result.returncode != 0:\r
raise RuntimeError(f"Export failed: {result.stderr}")\r
\r
return ifc_path.with_suffix('.xlsx')\r
\r
def batch_convert(self, folder: str,\r
include_subfolders: bool = True,\r
include_bbox: bool = True) -> List[Dict[str, Any]]:\r
"""Convert all IFC files in folder."""\r
folder_path = Path(folder)\r
pattern = "**/*.ifc" if include_subfolders else "*.ifc"\r
\r
results = []\r
for ifc_file in folder_path.glob(pattern):\r
try:\r
output = self.convert(str(ifc_file), include_bbox)\r
results.append({\r
'input': str(ifc_file),\r
'output': str(output),\r
'status': 'success'\r
})\r
print(f"✓ Converted: {ifc_file.name}")\r
except Exception as e:\r
results.append({\r
'input': str(ifc_file),\r
'output': None,\r
'status': 'failed',\r
'error': str(e)\r
})\r
print(f"✗ Failed: {ifc_file.name} - {e}")\r
\r
return results\r
\r
def read_elements(self, xlsx_file: str) -> pd.DataFrame:\r
"""Read converted Excel as DataFrame."""\r
return pd.read_excel(xlsx_file, sheet_name="Elements")\r
\r
def get_element_types(self, xlsx_file: str) -> pd.DataFrame:\r
"""Get element type summary."""\r
df = self.read_elements(xlsx_file)\r
\r
if 'IfcType' not in df.columns:\r
raise ValueError("IfcType column not found")\r
\r
summary = df.groupby('IfcType').agg({\r
'GlobalId': 'count',\r
'Volume': 'sum' if 'Volume' in df.columns else 'count',\r
'Area': 'sum' if 'Area' in df.columns else 'count'\r
}).reset_index()\r
\r
summary.columns = ['IFC_Type', 'Count', 'Total_Volume', 'Total_Area']\r
return summary.sort_values('Count', ascending=False)\r
\r
def get_levels(self, xlsx_file: str) -> pd.DataFrame:\r
"""Get building level summary."""\r
df = self.read_elements(xlsx_file)\r
\r
level_col = None\r
for col in ['Level', 'BuildingStorey', 'IfcBuildingStorey']:\r
if col in df.columns:\r
level_col = col\r
break\r
\r
if level_col is None:\r
return pd.DataFrame(columns=['Level', 'Element_Count'])\r
\r
summary = df.groupby(level_col).agg({\r
'GlobalId': 'count'\r
}).reset_index()\r
summary.columns = ['Level', 'Element_Count']\r
return summary\r
\r
def get_materials(self, xlsx_file: str) -> pd.DataFrame:\r
"""Get material summary."""\r
df = self.read_elements(xlsx_file)\r
\r
if 'Material' not in df.columns:\r
return pd.DataFrame(columns=['Material', 'Count'])\r
\r
summary = df.groupby('Material').agg({\r
'GlobalId': 'count'\r
}).reset_index()\r
summary.columns = ['Material', 'Element_Count']\r
return summary.sort_values('Element_Count', ascending=False)\r
\r
def get_quantities(self, xlsx_file: str,\r
group_by: str = 'IfcType') -> pd.DataFrame:\r
"""Get quantity takeoff summary."""\r
df = self.read_elements(xlsx_file)\r
\r
if group_by not in df.columns:\r
raise ValueError(f"Column {group_by} not found")\r
\r
agg_dict = {'GlobalId': 'count'}\r
\r
# Add numeric columns for aggregation\r
numeric_cols = ['Volume', 'Area', 'Length', 'Width', 'Height']\r
for col in numeric_cols:\r
if col in df.columns:\r
agg_dict[col] = 'sum'\r
\r
summary = df.groupby(group_by).agg(agg_dict).reset_index()\r
return summary\r
\r
def filter_by_type(self, xlsx_file: str,\r
ifc_types: List[str]) -> pd.DataFrame:\r
"""Filter elements by IFC type."""\r
df = self.read_elements(xlsx_file)\r
return df[df['IfcType'].isin(ifc_types)]\r
\r
def get_properties(self, xlsx_file: str,\r
element_id: str) -> Dict[str, Any]:\r
"""Get all properties for specific element."""\r
df = self.read_elements(xlsx_file)\r
element = df[df['GlobalId'] == element_id]\r
\r
if element.empty:\r
return {}\r
\r
# Convert row to dictionary, excluding NaN values\r
props = element.iloc[0].dropna().to_dict()\r
return props\r
\r
def validate_ifc_data(self, xlsx_file: str) -> Dict[str, Any]:\r
"""Validate IFC data quality."""\r
df = self.read_elements(xlsx_file)\r
\r
validation = {\r
'total_elements': len(df),\r
'issues': []\r
}\r
\r
# Check for missing GlobalIds\r
if 'GlobalId' in df.columns:\r
missing_ids = df['GlobalId'].isna().sum()\r
if missing_ids > 0:\r
validation['issues'].append(f"{missing_ids} elements missing GlobalId")\r
\r
# Check for missing names\r
if 'Name' in df.columns:\r
missing_names = df['Name'].isna().sum()\r
if missing_names > 0:\r
validation['issues'].append(f"{missing_names} elements missing Name")\r
\r
# Check for zero quantities\r
for col in ['Volume', 'Area']:\r
if col in df.columns:\r
zero_qty = (df[col] == 0).sum()\r
if zero_qty > 0:\r
validation['issues'].append(f"{zero_qty} elements with zero {col}")\r
\r
# Check for duplicate GlobalIds\r
if 'GlobalId' in df.columns:\r
duplicates = df['GlobalId'].duplicated().sum()\r
if duplicates > 0:\r
validation['issues'].append(f"{duplicates} duplicate GlobalIds")\r
\r
validation['is_valid'] = len(validation['issues']) == 0\r
return validation\r
\r
\r
class IFCQuantityTakeoff:\r
"""Quantity takeoff from IFC data."""\r
\r
def __init__(self, exporter: IFCExporter):\r
self.exporter = exporter\r
\r
def generate_qto(self, ifc_file: str) -> Dict[str, pd.DataFrame]:\r
"""Generate complete quantity takeoff."""\r
xlsx = self.exporter.convert(ifc_file, include_bbox=True)\r
df = self.exporter.read_elements(str(xlsx))\r
\r
qto = {}\r
\r
# Walls\r
walls = df[df['IfcType'].str.contains('Wall', case=False, na=False)]\r
if not walls.empty:\r
qto['Walls'] = self._summarize_elements(walls, 'Type Name')\r
\r
# Slabs\r
slabs = df[df['IfcType'].str.contains('Slab', case=False, na=False)]\r
if not slabs.empty:\r
qto['Slabs'] = self._summarize_elements(slabs, 'Type Name')\r
\r
# Columns\r
columns = df[df['IfcType'].str.contains('Column', case=False, na=False)]\r
if not columns.empty:\r
qto['Columns'] = self._summarize_elements(columns, 'Type Name')\r
\r
# Beams\r
beams = df[df['IfcType'].str.contains('Beam', case=False, na=False)]\r
if not beams.empty:\r
qto['Beams'] = self._summarize_elements(beams, 'Type Name')\r
\r
# Doors\r
doors = df[df['IfcType'].str.contains('Door', case=False, na=False)]\r
if not doors.empty:\r
qto['Doors'] = self._summarize_elements(doors, 'Type Name')\r
\r
# Windows\r
windows = df[df['IfcType'].str.contains('Window', case=False, na=False)]\r
if not windows.empty:\r
qto['Windows'] = self._summarize_elements(windows, 'Type Name')\r
\r
return qto\r
\r
def _summarize_elements(self, df: pd.DataFrame,\r
group_col: str) -> pd.DataFrame:\r
"""Summarize elements by grouping column."""\r
if group_col not in df.columns:\r
group_col = 'IfcType'\r
\r
agg_dict = {'GlobalId': 'count'}\r
for col in ['Volume', 'Area', 'Length']:\r
if col in df.columns:\r
agg_dict[col] = 'sum'\r
\r
summary = df.groupby(group_col).agg(agg_dict).reset_index()\r
summary.rename(columns={'GlobalId': 'Count'}, inplace=True)\r
return summary\r
\r
def export_to_excel(self, qto: Dict[str, pd.DataFrame],\r
output_file: str):\r
"""Export QTO to multi-sheet Excel."""\r
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:\r
for sheet_name, df in qto.items():\r
df.to_excel(writer, sheet_name=sheet_name, index=False)\r
\r
\r
# Convenience functions\r
def convert_ifc_to_excel(ifc_file: str,\r
exporter_path: str = "IfcExporter.exe") -> str:\r
"""Quick conversion of IFC to Excel."""\r
exporter = IFCExporter(exporter_path)\r
output = exporter.convert(ifc_file)\r
return str(output)\r
\r
\r
def get_ifc_summary(xlsx_file: str) -> Dict[str, Any]:\r
"""Get summary of converted IFC data."""\r
df = pd.read_excel(xlsx_file, sheet_name="Elements")\r
\r
return {\r
'total_elements': len(df),\r
'ifc_types': df['IfcType'].nunique() if 'IfcType' in df.columns else 0,\r
'levels': df['Level'].nunique() if 'Level' in df.columns else 0,\r
'total_volume': df['Volume'].sum() if 'Volume' in df.columns else 0,\r
'total_area': df['Area'].sum() if 'Area' in df.columns else 0\r
}\r
```\r
\r
## Output Structure\r
\r
### Excel Sheets\r
| Sheet | Content |\r
|-------|---------|\r
| Elements | All IFC elements with properties |\r
| Types | Element types summary |\r
| Levels | Building storey data |\r
| Materials | Material assignments |\r
| PropertySets | IFC property sets |\r
\r
### Element Columns\r
| Column | Type | Description |\r
|--------|------|-------------|\r
| GlobalId | string | IFC GUID |\r
| IfcType | string | IFC entity type |\r
| Name | string | Element name |\r
| Description | string | Element description |\r
| Level | string | Building storey |\r
| Material | string | Primary material |\r
| Volume | float | Volume (m³) |\r
| Area | float | Surface area (m²) |\r
| Length | float | Length (m) |\r
| Height | float | Height (m) |\r
| Width | float | Width (m) |\r
\r
## Quick Start\r
\r
```python\r
# Initialize exporter\r
exporter = IFCExporter("C:/DDC/IfcExporter.exe")\r
\r
# Convert IFC to Excel\r
xlsx = exporter.convert("C:/Models/Building.ifc", include_bbox=True)\r
\r
# Read elements\r
df = exporter.read_elements(str(xlsx))\r
print(f"Total elements: {len(df)}")\r
\r
# Get element types\r
types = exporter.get_element_types(str(xlsx))\r
print(types)\r
\r
# Get quantities by type\r
qto = exporter.get_quantities(str(xlsx), group_by='IfcType')\r
print(qto)\r
```\r
\r
## Common Use Cases\r
\r
### 1. Model Validation\r
```python\r
exporter = IFCExporter()\r
xlsx = exporter.convert("model.ifc")\r
validation = exporter.validate_ifc_data(str(xlsx))\r
\r
if not validation['is_valid']:\r
print("Issues found:")\r
for issue in validation['issues']:\r
print(f" - {issue}")\r
```\r
\r
### 2. Quantity Takeoff\r
```python\r
qto_generator = IFCQuantityTakeoff(exporter)\r
qto = qto_generator.generate_qto("building.ifc")\r
\r
for category, data in qto.items():\r
print(f"\
{category}:")\r
print(data.to_string(index=False))\r
```\r
\r
### 3. Material Schedule\r
```python\r
xlsx = exporter.convert("building.ifc")\r
materials = exporter.get_materials(str(xlsx))\r
print(materials)\r
```\r
\r
## Integration with DDC Pipeline\r
\r
```python\r
# Full pipeline: IFC → Excel → Validation → Cost Estimate\r
exporter = IFCExporter("C:/DDC/IfcExporter.exe")\r
\r
# 1. Convert IFC\r
xlsx = exporter.convert("project.ifc", include_bbox=True)\r
\r
# 2. Validate data\r
validation = exporter.validate_ifc_data(str(xlsx))\r
print(f"Valid: {validation['is_valid']}")\r
\r
# 3. Generate QTO\r
qto = IFCQuantityTakeoff(exporter)\r
quantities = qto.generate_qto("project.ifc")\r
\r
# 4. Export for cost estimation\r
qto.export_to_excel(quantities, "project_qto.xlsx")\r
```\r
\r
## Resources\r
\r
- **GitHub**: [cad2data Pipeline](https://github.com/datadrivenconstruction/cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto)\r
- **IFC Standard**: [buildingSMART](https://www.buildingsmart.org/standards/bsi-standards/industry-foundation-classes/)\r
- **DDC Book**: Chapter 2.4 - CAD/BIM Data Extraction\r
安全使用建议
This skill appears to do what it says (convert IFC files to Excel) but it expects you to have a separate CLI (IfcExporter.exe) or use IfcOpenShell. The skill metadata fails to declare that required binary and provides no homepage or install instructions. Before installing or running this skill:
- Verify the provenance of IfcExporter.exe if you intend to use it. Prefer well-known sources (official project sites or GitHub releases) or use IfcOpenShell (an established open-source alternative) instead.
- If you must download a binary, obtain it from an official/reputable release page and verify checksums/signatures when available.
- Run conversions in an isolated environment (container or VM) if you are unsure about the binary's origin, since the skill will execute that local program with access to files.
- Limit filesystem access to only the directories containing IFC files and outputs, and avoid granting broad system-wide access.
The main red flag is the metadata/instructions mismatch and missing provenance for the external CLI; these are likely oversights but could be exploited if an attacker convinces you to install an untrusted binary. If the author can provide an official download URL, checksums, or switch the skill to use IfcOpenShell (with clear install guidance), the concern would be resolved.
功能分析
Type: OpenClaw Skill
Name: ifc-to-excel
Version: 2.0.0
The skill is classified as suspicious due to its reliance on executing an external CLI tool (`IfcExporter.exe`) via `subprocess.run` in `SKILL.md`. While `subprocess.run` is used with a list of arguments (safer than `shell=True`), the `exporter_path` and `ifc_file` parameters are user-controlled inputs. If a malicious prompt could manipulate these paths, it could lead to arbitrary command execution (e.g., executing `calc.exe` by providing its path as the `ifc_file`). This represents a vulnerability (potential RCE) rather than clear malicious intent, as the stated purpose and code logic are otherwise aligned with IFC to Excel conversion.
能力评估
Purpose & Capability
The name/description and instructions consistently describe converting IFC to Excel using an external CLI (IfcExporter.exe) or IfcOpenShell. However, the skill declares no required binaries or credentials in its metadata even though the runtime explicitly depends on a local executable (IfcExporter.exe) or IfcOpenShell. That mismatch (metadata says 'none' but SKILL.md requires a binary) is incoherent and could mislead users about what will actually run.
Instruction Scope
The SKILL.md instructions are narrowly scoped to reading IFC files from disk, invoking a local CLI, and writing Excel/DAE outputs. There are no instructions to read unrelated system files or environment variables, nor to transmit data remotely. The Python examples call subprocess.run to invoke the CLI and check file existence; that is expected for this task. One note: the instructions assume the presence of IfcExporter.exe and IfcOpenShell but do not explain how/where to obtain or verify those binaries.
Install Mechanism
There is no install spec (instruction-only), which is low-risk by itself. However, because the runtime depends on an external executable (IfcExporter.exe) of unknown origin, the lack of an install mechanism means users may download that binary from an untrusted source. The skill does not link to an official homepage or release host or describe trusted installation steps (e.g., use IfcOpenShell from its official project).
Credentials
The skill does not request environment variables, credentials, or config paths beyond filesystem access. The declared permission for filesystem access matches the stated need to read IFC and write Excel files. There are no excessive credential requests.
Persistence & Privilege
The skill is not marked always:true and is user-invocable. It does require filesystem permission (declared in claw.json), which is proportionate to its function. It does not request elevated or persistent privileges or attempt to modify other skills' configurations.
如何使用
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install ifc-to-excel - 安装完成后,直接呼叫该 Skill 的名称或使用
/ifc-to-excel触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v2.0.0
Major update with new features and improved usability.
- Added support for IFC4x1 and IFC4x3 schemas, including full infrastructure alignment and latest standards.
- Enables export of 3D geometry to Collada DAE format alongside Excel, with matching element IDs for correlation.
- Introduced CLI options for selective export (Excel only, 3D only, include bounding boxes).
- Improved batch processing: convert multiple IFC files recursively from folders via command line or Python.
- Provided Python integration with a detailed API for conversion, reading, filtering, and summarizing results in Excel.
- Documentation overhaul with clear business use cases, CLI usage examples, and schema/entity reference.
v1.0.0
IFC To Excel 1.0.0 – Initial Release
- Convert IFC files (2x3, 4x1, 4x3) to structured Excel (.xlsx) databases using the IfcExporter CLI
- Extract BIM data: properties, quantities, materials, and optional bounding box geometry
- Optional export of 3D geometry to Collada DAE format
- Supports batch processing and CLI or Python usage
- No proprietary BIM software or licenses required; works offline
元数据
常见问题
Ifc To Excel 是什么?
Convert IFC files (2x3, 4x1, 4x3) to Excel databases using IfcExporter CLI. Extract BIM data, properties, and geometry without proprietary software. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 1220 次。
如何安装 Ifc To Excel?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install ifc-to-excel」即可一键安装,无需额外配置。
Ifc To Excel 是免费的吗?
是的,Ifc To Excel 完全免费(开源免费),可自由下载、安装和使用。
Ifc To Excel 支持哪些平台?
Ifc To Excel 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 Ifc To Excel?
由 datadrivenconstruction(@datadrivenconstruction)开发并维护,当前版本 v2.0.0。
推荐 Skills