@@ -145,33 +145,31 @@ def __repr__(self):
145145
146146
147147class Table :
148- """Represents a full-featured AutoCAD table."""
149- def __init__ ( self , insertion_point : APoint , data : list [ list [ str ]], headers : list [ str ] = None , title : str = None ,
150- col_widths : list [float ] = None , row_height : float = 8.0 , text_height : float = 2.5 ,
151- alignment : Alignment = Alignment . CENTER ):
148+ """Represents a data table to be drawn in AutoCAD ."""
149+
150+ def __init__ ( self , insertion_point : APoint , data : list [list [ str ]], headers : list [ str ] = None ,
151+ col_widths : list [ float ] = None , row_height : float = 8.0 , text_height : float = 2.5 , text_style : str = None ):
152152 """
153153 Initializes a table data object.
154154 Args:
155155 insertion_point (APoint): The top-left insertion point for the table.
156156 data (list[list[str]]): A list of lists representing the table's body data.
157157 headers (list[str], optional): A list of strings for the header row. Defaults to None.
158- title (str, optional): A title for the table. Defaults to None.
159- col_widths (list[float], optional): A list of widths for each column. If None, widths are automatic.
158+ col_widths (list[float], optional): A list of widths for each column.
160159 row_height (float): The height for each row.
161160 text_height (float): The default text height for cells.
162- alignment (Alignment ): The alignment for cell content . Defaults to Alignment.CENTER .
161+ text_style (str, optional ): The text style to use . Defaults to None (use default) .
163162 """
164163 self .insertion_point = insertion_point
165164 self .data = data
166165 self .headers = headers
167- self .title = title
168166 self .col_widths = col_widths
169167 self .row_height = row_height
170168 self .text_height = text_height
171- self .alignment = alignment
169+ self .text_style = text_style
172170
173171 def __repr__ (self ):
174- return f"Table(title=' { self . title } ', rows={ len (self .data )} , cols={ len (self .data [0 ]) if self .data else 0 } )"
172+ return f"Table(rows={ len (self .data )} , cols={ len (self .data [0 ]) if self .data else 0 } , text_style= { self . text_style } )"
175173
176174
177175class Text :
@@ -1188,23 +1186,51 @@ def select_group(self, group_name):
11881186 except Exception as e :
11891187 raise CADException (f"Error selecting group '{ group_name } ': { e } " )
11901188
1191- def add_mtext (self , content : str , insertion_point : APoint , width : float , height : float ):
1189+ def add_mtext (self , content : str , insertion_point : APoint , width : float , height : float , text_style : str = None ,
1190+ attachment_point : int = 1 ):
11921191 """
1193- Adds a multiline text (MText) object to the model space.
1192+ Adds a multiline text (MText) object to the model space with specified alignment.
1193+
11941194 Args:
11951195 content (str): The text string to display. Can include newlines.
1196- insertion_point (APoint): The insertion point for the top-left corner of the text box .
1196+ insertion_point (APoint): The insertion point for the text, relative to the alignment .
11971197 width (float): The width of the MText bounding box.
11981198 height (float): The height of the text characters.
1199+ text_style (str, optional): The name of the text style to use. Defaults to None (use default).
1200+ attachment_point (int): The COM constant for the attachment point (e.g., 1 for TopLeft, 5 for MiddleCenter).
1201+
11991202 Returns:
12001203 The created MText object.
12011204
12021205 Raises:
12031206 CADException: If the MText object cannot be added.
12041207 """
12051208 try :
1206- mtext_obj = self .modelspace .AddMText (insertion_point .to_variant (), width , content )
1209+ temp_point = APoint (0 , 0 , 0 )
1210+ mtext_obj = self .modelspace .AddMText (temp_point .to_variant (), width , content )
12071211 mtext_obj .Height = height
1212+
1213+ mtext_obj .AttachmentPoint = attachment_point
1214+ if text_style :
1215+ text_styles = self .doc .TextStyles
1216+ style_exists = False
1217+ for style in text_styles :
1218+ if style .Name .lower () == text_style .lower ():
1219+ style_exists = True
1220+ break
1221+
1222+ if style_exists :
1223+ try :
1224+ mtext_obj .StyleName = text_style
1225+ except Exception as e :
1226+ print (f"Error setting TextStyle '{ text_style } ': { e } . Using default." )
1227+ mtext_obj .StyleName = "Standard"
1228+ else :
1229+ print (f"Warning: TextStyle '{ text_style } ' not found in drawing. Using 'Standard' style." )
1230+ mtext_obj .StyleName = "Standard"
1231+
1232+ mtext_obj .InsertionPoint = insertion_point .to_variant ()
1233+
12081234 return mtext_obj
12091235 except Exception as e :
12101236 raise CADException (f"Error adding MText: { e } " )
@@ -1240,78 +1266,93 @@ def zoom_to_object(self, obj):
12401266
12411267 def add_table (self , table_obj : Table ):
12421268 """
1243- Adds a fully-featured table to the model space from a Table object.
1269+ Adds a table to the model space by manually drawing lines and text.
1270+ This version is optimized for tables with headers and data only (no title)
1271+ and provides precise text alignment within each cell.
1272+
12441273 Args:
12451274 table_obj (Table): The Table data object to draw.
1246- Returns:
1247- The created AutoCAD table object.
12481275 Raises:
12491276 CADException: If the table cannot be created or data is inconsistent.
12501277 """
12511278 try :
12521279 if not table_obj .data or not isinstance (table_obj .data [0 ], list ):
12531280 raise ValueError ("Input 'data' must be a non-empty list of lists." )
1254-
1255- num_data_rows = len (table_obj .data )
12561281 num_cols = len (table_obj .data [0 ])
1257-
1282+ if num_cols == 0 :
1283+ raise ValueError ("Input 'data' must contain at least one column." )
12581284 if table_obj .headers and len (table_obj .headers ) != num_cols :
12591285 raise ValueError ("Number of headers must match the number of columns in data." )
1286+ if not table_obj .col_widths or len (table_obj .col_widths ) != num_cols :
1287+ raise ValueError ("A list of column widths matching the number of columns is required for manual creation." )
12601288
1261- total_rows = num_data_rows
1262- has_title = table_obj .title is not None
1263- has_headers = table_obj .headers is not None
1264- if has_title :
1265- total_rows += 1
1266- if has_headers :
1267- total_rows += 1
1268-
1269- default_col_width = 20.0
1270- if table_obj .col_widths and table_obj .col_widths [0 ] > 0 :
1271- default_col_width = table_obj .col_widths [0 ]
1272-
1273- table = self .modelspace .AddTable (table_obj .insertion_point .to_variant (), total_rows , num_cols ,
1274- table_obj .row_height , default_col_width )
1275-
1276- alignment_map = {
1277- Alignment .LEFT : 4 ,
1278- Alignment .CENTER : 5 ,
1279- Alignment .RIGHT : 6 ,
1280- }
1281- acad_alignment = alignment_map .get (table_obj .alignment , 5 )
1282-
1283- table .SetTextHeight (table_obj .text_height )
1284- table .SetAlignment (acad_alignment )
1285-
1286- current_row = 0
1287- if has_title :
1288- table .SetRowType (current_row , 1 )
1289- table .SetText (current_row , 0 , table_obj .title )
1290- table .MergeCells (current_row , 0 , current_row , num_cols - 1 )
1291- current_row += 1
1292-
1293- if has_headers :
1294- table .SetRowType (current_row , 2 )
1295- for col_idx , header_text in enumerate (table_obj .headers ):
1296- table .SetText (current_row , col_idx , header_text )
1297- current_row += 1
1289+ ip = table_obj .insertion_point
1290+ col_widths = table_obj .col_widths
1291+ row_height = table_obj .row_height
1292+ total_width = sum (col_widths )
12981293
1299- for row_idx , data_row in enumerate (table_obj .data ):
1300- if len (data_row ) != num_cols :
1301- raise ValueError (f"Inconsistent number of columns in data row { row_idx } ." )
1302- for col_idx , cell_text in enumerate (data_row ):
1303- table .SetText (current_row + row_idx , col_idx , str (cell_text ))
1294+ num_data_rows = len (table_obj .data )
1295+ num_header_rows = 1 if table_obj .headers else 0
1296+ num_total_rows = num_header_rows + num_data_rows
1297+ total_height = num_total_rows * row_height
1298+
1299+ current_y = ip .y
1300+ for _ in range (num_total_rows + 1 ):
1301+ self .add_line (APoint (ip .x , current_y ), APoint (ip .x + total_width , current_y ))
1302+ current_y -= row_height
13041303
1305- if table_obj . col_widths :
1306- if len ( table_obj . col_widths ) != num_cols :
1307- raise ValueError ( "Number of column widths must match the number of columns." )
1308- for i , width in enumerate ( table_obj . col_widths ):
1309- table . SetColumnWidth ( i , width )
1304+ current_x = ip . x
1305+ for width in col_widths :
1306+ self . add_line ( APoint ( current_x , ip . y ), APoint ( current_x , ip . y - total_height ) )
1307+ current_x += width
1308+ self . add_line ( APoint ( ip . x + total_width , ip . y ), APoint ( ip . x + total_width , ip . y - total_height ) )
13101309
1311- table .GenerateLayout ()
1312- return table
1310+ acAttachmentPointMiddleCenter = 5
1311+
1312+ current_y = ip .y
1313+
1314+ # Header Row
1315+ if table_obj .headers :
1316+ current_x = ip .x
1317+ for col_idx , header_text in enumerate (table_obj .headers ):
1318+ cell_width = col_widths [col_idx ]
1319+
1320+ cell_center_x = current_x + (cell_width / 2 )
1321+ cell_center_y = current_y - (row_height / 2 )
1322+
1323+ mtext_obj = self .add_mtext (
1324+ content = str (header_text ),
1325+ insertion_point = APoint (cell_center_x , cell_center_y ),
1326+ width = cell_width * 0.95 ,
1327+ height = table_obj .text_height ,
1328+ text_style = table_obj .text_style ,
1329+ attachment_point = acAttachmentPointMiddleCenter
1330+ )
1331+ mtext_obj .AttachmentPoint = acAttachmentPointMiddleCenter
1332+ current_x += cell_width
1333+ current_y -= row_height
1334+
1335+ for data_row in table_obj .data :
1336+ current_x = ip .x
1337+ for col_idx , cell_text in enumerate (data_row ):
1338+ cell_width = col_widths [col_idx ]
1339+
1340+ cell_center_x = current_x + (cell_width / 2 )
1341+ cell_center_y = current_y - (row_height / 2 )
1342+
1343+ mtext_obj = self .add_mtext (
1344+ content = str (cell_text ),
1345+ insertion_point = APoint (cell_center_x , cell_center_y ),
1346+ width = cell_width * 0.95 ,
1347+ height = table_obj .text_height ,
1348+ text_style = table_obj .text_style ,
1349+ attachment_point = acAttachmentPointMiddleCenter # Pass alignment directly
1350+ )
1351+ mtext_obj .AttachmentPoint = acAttachmentPointMiddleCenter
1352+ current_x += cell_width
1353+ current_y -= row_height
13131354
13141355 except ValueError as ve :
1315- raise CADException (f"Invalid input for table creation: { ve } " )
1356+ raise CADException (f"Invalid input for manual table creation: { ve } " )
13161357 except Exception as e :
1317- raise CADException (f"Error adding table: { e } " )
1358+ raise CADException (f"Error during manual table creation : { e } " )
0 commit comments