mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 21:53:40 +00:00
IfcFM now uses Openpyxl and supports xlsx. Reorder columns to be more logical and group similar data types together (at least for me).
This commit is contained in:
+64
-25
@@ -29,7 +29,8 @@ import ifcopenshell.util.placement
|
|||||||
import ifcopenshell.util.classification
|
import ifcopenshell.util.classification
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from xlsxwriter import Workbook
|
from openpyxl import Workbook
|
||||||
|
from openpyxl.styles import PatternFill
|
||||||
except:
|
except:
|
||||||
pass # No XLSX support
|
pass # No XLSX support
|
||||||
|
|
||||||
@@ -123,25 +124,25 @@ class Writer:
|
|||||||
if preset == "BASIC":
|
if preset == "BASIC":
|
||||||
self.config = {
|
self.config = {
|
||||||
"Actors": {"colours": "ppssssssss", "sort": [{"name": "Name", "order": "ASC"}]},
|
"Actors": {"colours": "ppssssssss", "sort": [{"name": "Name", "order": "ASC"}]},
|
||||||
"Facilities": {"colours": "prppppsssseeee", "sort": [{"name": "Name", "order": "ASC"}]},
|
"Facilities": {"colours": "ppppreeeeessss", "sort": [{"name": "Name", "order": "ASC"}]},
|
||||||
"Storeys": {
|
"Storeys": {
|
||||||
"colours": "prppeees",
|
"colours": "ppreeees",
|
||||||
"sort": [{"name": "Elevation", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
"sort": [{"name": "Elevation", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
||||||
},
|
},
|
||||||
"Spaces": {
|
"Spaces": {
|
||||||
"colours": "prpprpeess",
|
"colours": "ppprreeess",
|
||||||
"sort": [{"name": "LevelName", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
"sort": [{"name": "LevelName", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
||||||
},
|
},
|
||||||
"Zones": {"colours": "prpree", "sort": [{"name": "Name", "order": "ASC"}]},
|
"Zones": {"colours": "prreee", "sort": [{"name": "Name", "order": "ASC"}]},
|
||||||
"Types": {
|
"Types": {
|
||||||
"colours": "prpppeeee",
|
"colours": "pppreeeee",
|
||||||
"sort": [{"name": "ModelObject", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
"sort": [{"name": "ModelObject", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
||||||
},
|
},
|
||||||
"Elements": {
|
"Elements": {
|
||||||
"colours": "prprrreee",
|
"colours": "prrrreeee",
|
||||||
"sort": [{"name": "TypeName", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
"sort": [{"name": "TypeName", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
||||||
},
|
},
|
||||||
"Systems": {"colours": "pprppee", "sort": [{"name": "Name", "order": "ASC"}]},
|
"Systems": {"colours": "pppreee", "sort": [{"name": "Name", "order": "ASC"}]},
|
||||||
}
|
}
|
||||||
|
|
||||||
def write(self, null="N/A", empty="-", bool_true="YES", bool_false="NO"):
|
def write(self, null="N/A", empty="-", bool_true="YES", bool_false="NO"):
|
||||||
@@ -234,6 +235,44 @@ class Writer:
|
|||||||
|
|
||||||
doc.save(output, True)
|
doc.save(output, True)
|
||||||
|
|
||||||
|
def write_xlsx(self, output):
|
||||||
|
workbook = Workbook()
|
||||||
|
|
||||||
|
cell_formats = {}
|
||||||
|
for key, value in self.colours.items():
|
||||||
|
fill = PatternFill(start_color=value, end_color=value, fill_type="solid")
|
||||||
|
cell_formats[key] = fill
|
||||||
|
|
||||||
|
for category, data in self.categories.items():
|
||||||
|
colours = self.config.get(category, {}).get("colours", [])
|
||||||
|
|
||||||
|
if category in workbook.sheetnames:
|
||||||
|
worksheet = workbook[category]
|
||||||
|
else:
|
||||||
|
worksheet = workbook.create_sheet(category)
|
||||||
|
|
||||||
|
r = 1 # Openpyxl uses 1-based indexing
|
||||||
|
c = 1
|
||||||
|
for header in data["headers"]:
|
||||||
|
cell = worksheet.cell(row=r, column=c, value=header)
|
||||||
|
cell.fill = cell_formats["h"]
|
||||||
|
c += 1
|
||||||
|
|
||||||
|
r += 1
|
||||||
|
for row in data["rows"]:
|
||||||
|
c = 1
|
||||||
|
for col in row:
|
||||||
|
if c > len(colours): # Adjusted the comparison
|
||||||
|
cell_format = "n"
|
||||||
|
else:
|
||||||
|
cell_format = colours[c - 1] # Adjusted the indexing
|
||||||
|
cell = worksheet.cell(row=r, column=c, value=col)
|
||||||
|
cell.fill = cell_formats[cell_format]
|
||||||
|
c += 1
|
||||||
|
r += 1
|
||||||
|
|
||||||
|
workbook.save(output)
|
||||||
|
|
||||||
|
|
||||||
def get_actors(ifc_file):
|
def get_actors(ifc_file):
|
||||||
return ifc_file.by_type("IfcActor")
|
return ifc_file.by_type("IfcActor")
|
||||||
@@ -295,19 +334,19 @@ def get_facility_data(ifc_file, element):
|
|||||||
return {
|
return {
|
||||||
"key": element.Name,
|
"key": element.Name,
|
||||||
"Name": element.Name,
|
"Name": element.Name,
|
||||||
"AuthorOrganizationName": get_owner_name(element),
|
|
||||||
"AuthorDate": get_owner_creation_date(ifc_file.by_type("IfcProject")[0]),
|
|
||||||
"Category": get_classification(element),
|
|
||||||
"ProjectName": ifc_file.by_type("IfcProject")[0].Name,
|
"ProjectName": ifc_file.by_type("IfcProject")[0].Name,
|
||||||
"SiteName": getattr(get_facility_parent(element, "IfcSite"), "Name", None),
|
"SiteName": getattr(get_facility_parent(element, "IfcSite"), "Name", None),
|
||||||
"LinearUnits": "millimeters",
|
"Category": get_classification(element),
|
||||||
"AreaUnits": "square meters",
|
"AuthorOrganizationName": get_owner_name(element),
|
||||||
"AreaMeasurement": "BIM Software",
|
"AuthorDate": get_owner_creation_date(ifc_file.by_type("IfcProject")[0]),
|
||||||
"Phase": ifc_file.by_type("IfcProject")[0].Phase,
|
|
||||||
"ModelSoftware": get_owner_application(element),
|
"ModelSoftware": get_owner_application(element),
|
||||||
"ModelProjectID": ifc_file.by_type("IfcProject")[0].GlobalId,
|
"ModelProjectID": ifc_file.by_type("IfcProject")[0].GlobalId,
|
||||||
"ModelSiteID": getattr(get_facility_parent(element, "IfcSite"), "GlobalId", None),
|
"ModelSiteID": getattr(get_facility_parent(element, "IfcSite"), "GlobalId", None),
|
||||||
"ModelBuildingID": element.GlobalId,
|
"ModelBuildingID": element.GlobalId,
|
||||||
|
"LinearUnits": "millimeters",
|
||||||
|
"AreaUnits": "square meters",
|
||||||
|
"AreaMeasurement": "BIM Software",
|
||||||
|
"Phase": ifc_file.by_type("IfcProject")[0].Phase,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -315,9 +354,9 @@ def get_storey_data(ifc_file, element):
|
|||||||
return {
|
return {
|
||||||
"key": element.Name,
|
"key": element.Name,
|
||||||
"Name": element.Name,
|
"Name": element.Name,
|
||||||
|
"Category": "Level",
|
||||||
"AuthorOrganizationName": get_owner_name(element),
|
"AuthorOrganizationName": get_owner_name(element),
|
||||||
"AuthorDate": get_owner_creation_date(element),
|
"AuthorDate": get_owner_creation_date(element),
|
||||||
"Category": "Level",
|
|
||||||
"ModelSoftware": get_owner_application(element),
|
"ModelSoftware": get_owner_application(element),
|
||||||
"ModelObject": element.is_a(),
|
"ModelObject": element.is_a(),
|
||||||
"ModelID": element.GlobalId,
|
"ModelID": element.GlobalId,
|
||||||
@@ -330,11 +369,11 @@ def get_space_data(ifc_file, element):
|
|||||||
return {
|
return {
|
||||||
"key": element.Name,
|
"key": element.Name,
|
||||||
"Name": element.Name,
|
"Name": element.Name,
|
||||||
"AuthorOrganizationName": get_owner_name(element),
|
"Description": element.LongName,
|
||||||
"AuthorDate": get_owner_creation_date(element),
|
|
||||||
"Category": get_classification(element),
|
"Category": get_classification(element),
|
||||||
"LevelName": getattr(get_facility_parent(element, "IfcBuildingStorey"), "Name", None),
|
"LevelName": getattr(get_facility_parent(element, "IfcBuildingStorey"), "Name", None),
|
||||||
"Description": element.LongName,
|
"AuthorOrganizationName": get_owner_name(element),
|
||||||
|
"AuthorDate": get_owner_creation_date(element),
|
||||||
"ModelSoftware": get_owner_application(element),
|
"ModelSoftware": get_owner_application(element),
|
||||||
"ModelID": element.GlobalId,
|
"ModelID": element.GlobalId,
|
||||||
"AreaGross": get_property(psets, "Qto_SpaceBaseQuantities", "GrossFloorArea", decimals=2),
|
"AreaGross": get_property(psets, "Qto_SpaceBaseQuantities", "GrossFloorArea", decimals=2),
|
||||||
@@ -347,9 +386,9 @@ def get_zone_data(ifc_file, element):
|
|||||||
return {
|
return {
|
||||||
"key": (element.Name or "Unnamed") + (space.Name or "Unnamed"),
|
"key": (element.Name or "Unnamed") + (space.Name or "Unnamed"),
|
||||||
"Name": zone.Name,
|
"Name": zone.Name,
|
||||||
|
"SpaceName": space.Name,
|
||||||
"AuthorOrganizationName": get_owner_name(zone),
|
"AuthorOrganizationName": get_owner_name(zone),
|
||||||
"AuthorDate": get_owner_creation_date(zone),
|
"AuthorDate": get_owner_creation_date(zone),
|
||||||
"SpaceName": space.Name,
|
|
||||||
"ModelSoftware": get_owner_application(zone),
|
"ModelSoftware": get_owner_application(zone),
|
||||||
"ModelID": zone.GlobalId,
|
"ModelID": zone.GlobalId,
|
||||||
}
|
}
|
||||||
@@ -359,10 +398,10 @@ def get_type_data(ifc_file, element):
|
|||||||
return {
|
return {
|
||||||
"key": element.Name,
|
"key": element.Name,
|
||||||
"Name": element.Name,
|
"Name": element.Name,
|
||||||
|
"Description": element.Description,
|
||||||
|
"Category": get_classification(element),
|
||||||
"AuthorOrganizationName": get_owner_name(element),
|
"AuthorOrganizationName": get_owner_name(element),
|
||||||
"AuthorDate": get_owner_creation_date(element),
|
"AuthorDate": get_owner_creation_date(element),
|
||||||
"Category": get_classification(element),
|
|
||||||
"Description": element.Description,
|
|
||||||
"ModelSoftware": get_owner_application(element),
|
"ModelSoftware": get_owner_application(element),
|
||||||
"ModelObject": "{}[{}]".format(element.is_a(), ifcopenshell.util.element.get_predefined_type(element)),
|
"ModelObject": "{}[{}]".format(element.is_a(), ifcopenshell.util.element.get_predefined_type(element)),
|
||||||
"ModelTag": element.Tag,
|
"ModelTag": element.Tag,
|
||||||
@@ -378,11 +417,11 @@ def get_element_data(ifc_file, element):
|
|||||||
return {
|
return {
|
||||||
"key": element.Name,
|
"key": element.Name,
|
||||||
"Name": element.Name,
|
"Name": element.Name,
|
||||||
"AuthorOrganizationName": get_owner_name(element),
|
|
||||||
"AuthorDate": get_owner_creation_date(element),
|
|
||||||
"TypeName": ifcopenshell.util.element.get_type(element).Name,
|
"TypeName": ifcopenshell.util.element.get_type(element).Name,
|
||||||
"SpaceName": space_name,
|
"SpaceName": space_name,
|
||||||
"SystemName": system,
|
"SystemName": system,
|
||||||
|
"AuthorOrganizationName": get_owner_name(element),
|
||||||
|
"AuthorDate": get_owner_creation_date(element),
|
||||||
"ModelSoftware": get_owner_application(element),
|
"ModelSoftware": get_owner_application(element),
|
||||||
"ModelObject": "{}[{}]".format(element.is_a(), ifcopenshell.util.element.get_predefined_type(element)),
|
"ModelObject": "{}[{}]".format(element.is_a(), ifcopenshell.util.element.get_predefined_type(element)),
|
||||||
"ModelID": element.GlobalId,
|
"ModelID": element.GlobalId,
|
||||||
@@ -394,9 +433,9 @@ def get_system_data(ifc_file, element):
|
|||||||
"key": element.Name,
|
"key": element.Name,
|
||||||
"Name": element.Name,
|
"Name": element.Name,
|
||||||
"Description": element.Description,
|
"Description": element.Description,
|
||||||
|
"Category": get_classification(element),
|
||||||
"AuthorOrganizationName": get_owner_name(element),
|
"AuthorOrganizationName": get_owner_name(element),
|
||||||
"AuthorDate": get_owner_creation_date(element),
|
"AuthorDate": get_owner_creation_date(element),
|
||||||
"Category": get_classification(element),
|
|
||||||
"ModelSoftware": get_owner_application(element),
|
"ModelSoftware": get_owner_application(element),
|
||||||
"ModelID": element.GlobalId,
|
"ModelID": element.GlobalId,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user