refactor: excel parse
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# Copyright (c) 2011-2022, Manfred Moitzi
|
||||
# License: MIT License
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING, Iterable, Sequence, Optional
|
||||
import logging
|
||||
from ezdxf.lldxf.const import DXFStructureError, DXF12
|
||||
from .table import (
|
||||
Table,
|
||||
ViewportTable,
|
||||
TextstyleTable,
|
||||
LayerTable,
|
||||
LinetypeTable,
|
||||
AppIDTable,
|
||||
ViewTable,
|
||||
BlockRecordTable,
|
||||
DimStyleTable,
|
||||
UCSTable,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ezdxf.document import Drawing
|
||||
from ezdxf.entities import DXFEntity, DXFTagStorage
|
||||
from ezdxf.lldxf.tagwriter import AbstractTagWriter
|
||||
|
||||
logger = logging.getLogger("ezdxf")
|
||||
|
||||
TABLENAMES = {
|
||||
"LAYER": "layers",
|
||||
"LTYPE": "linetypes",
|
||||
"APPID": "appids",
|
||||
"DIMSTYLE": "dimstyles",
|
||||
"STYLE": "styles",
|
||||
"UCS": "ucs",
|
||||
"VIEW": "views",
|
||||
"VPORT": "viewports",
|
||||
"BLOCK_RECORD": "block_records",
|
||||
}
|
||||
|
||||
|
||||
class TablesSection:
|
||||
def __init__(self, doc: Drawing, entities: Optional[list[DXFEntity]] = None):
|
||||
assert doc is not None
|
||||
self.doc = doc
|
||||
# not loaded tables: table.doc is None
|
||||
self.layers = LayerTable()
|
||||
self.linetypes = LinetypeTable()
|
||||
self.appids = AppIDTable()
|
||||
self.dimstyles = DimStyleTable()
|
||||
self.styles = TextstyleTable()
|
||||
self.ucs = UCSTable()
|
||||
self.views = ViewTable()
|
||||
self.viewports = ViewportTable()
|
||||
self.block_records = BlockRecordTable()
|
||||
|
||||
if entities is not None:
|
||||
self._load(entities)
|
||||
self._reset_not_loaded_tables()
|
||||
|
||||
def tables(self) -> Sequence[Table]:
|
||||
return (
|
||||
self.layers,
|
||||
self.linetypes,
|
||||
self.appids,
|
||||
self.dimstyles,
|
||||
self.styles,
|
||||
self.ucs,
|
||||
self.views,
|
||||
self.viewports,
|
||||
self.block_records,
|
||||
)
|
||||
|
||||
def _load(self, entities: list[DXFEntity]) -> None:
|
||||
section_head: "DXFTagStorage" = entities[0] # type: ignore
|
||||
if section_head.dxftype() != "SECTION" or section_head.base_class[
|
||||
1
|
||||
] != (2, "TABLES"):
|
||||
raise DXFStructureError(
|
||||
"Critical structure error in TABLES section."
|
||||
)
|
||||
del entities[0] # delete first entity (0, SECTION)
|
||||
|
||||
table_records: list[DXFEntity] = []
|
||||
table_name = None
|
||||
for entity in entities:
|
||||
if entity.dxftype() == "TABLE":
|
||||
if len(table_records):
|
||||
# TABLE entity without preceding ENDTAB entity, should we care?
|
||||
logger.debug(
|
||||
f'Ignore missing ENDTAB entity in table "{table_name}".'
|
||||
)
|
||||
self._load_table(table_name, table_records) # type: ignore
|
||||
table_name = entity.dxf.name
|
||||
table_records = [entity] # collect table head
|
||||
elif entity.dxftype() == "ENDTAB": # do not collect (0, 'ENDTAB')
|
||||
self._load_table(table_name, table_records) # type: ignore
|
||||
table_records = (
|
||||
[]
|
||||
) # collect entities outside of tables, but ignore it
|
||||
else: # collect table entries
|
||||
table_records.append(entity)
|
||||
|
||||
if len(table_records):
|
||||
# last ENDTAB entity is missing, should we care?
|
||||
logger.debug(
|
||||
'Ignore missing ENDTAB entity in table "{}".'.format(table_name)
|
||||
)
|
||||
self._load_table(table_name, table_records) # type: ignore
|
||||
|
||||
def _load_table(
|
||||
self, name: str, table_entities: Iterable[DXFEntity]
|
||||
) -> None:
|
||||
"""
|
||||
Load table from tags.
|
||||
|
||||
Args:
|
||||
name: table name e.g. VPORT
|
||||
table_entities: iterable of table records
|
||||
|
||||
"""
|
||||
table = getattr(self, TABLENAMES[name])
|
||||
if isinstance(table, Table):
|
||||
table.load(self.doc, iter(table_entities))
|
||||
|
||||
def _reset_not_loaded_tables(self) -> None:
|
||||
entitydb = self.doc.entitydb
|
||||
for table in self.tables():
|
||||
if table.doc is None:
|
||||
handle = entitydb.next_handle()
|
||||
table.reset(self.doc, handle)
|
||||
entitydb.add(table.head)
|
||||
|
||||
def export_dxf(self, tagwriter: AbstractTagWriter) -> None:
|
||||
tagwriter.write_str(" 0\nSECTION\n 2\nTABLES\n")
|
||||
version = tagwriter.dxfversion
|
||||
self.viewports.export_dxf(tagwriter)
|
||||
self.linetypes.export_dxf(tagwriter)
|
||||
self.layers.export_dxf(tagwriter)
|
||||
self.styles.export_dxf(tagwriter)
|
||||
self.views.export_dxf(tagwriter)
|
||||
self.ucs.export_dxf(tagwriter)
|
||||
self.appids.export_dxf(tagwriter)
|
||||
self.dimstyles.export_dxf(tagwriter)
|
||||
if version > DXF12:
|
||||
self.block_records.export_dxf(tagwriter)
|
||||
tagwriter.write_tag2(0, "ENDSEC")
|
||||
|
||||
def create_table_handles(self):
|
||||
# DXF R12: TABLE does not require a handle and owner tag
|
||||
# DXF R2000+: TABLE requires a handle and an owner tag
|
||||
for table in self.tables():
|
||||
handle = self.doc.entitydb.next_handle()
|
||||
table.set_handle(handle)
|
||||
Reference in New Issue
Block a user