Tables — cell content, formatting, row/column ops, merging, styles, data linking
Use this skill when creating or modifying Table objects - creating tables, setting cell content (text, blocks, fields), formatting cells, inserting/deleting rows and columns, merging cells, and managing table styles.
Table inherits from BlockReference. Insert it into model/paper space like any other entity.
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
Table table = new Table();
table.TableStyle = db.Tablestyle; // current table style
table.Position = new Point3d(0, 0, 0);
// Set size first, then dimensions
table.SetSize(5, 3); // 5 rows, 3 columns (includes title + header rows)
table.SetRowHeight(8.0); // uniform row height
table.SetColumnWidth(40.0); // uniform column width
// Set individual column widths
table.Columns[0].Width = 20.0;
table.Columns[1].Width = 50.0;
table.Columns[2].Width = 30.0;
// Populate cells (row 0 = title, row 1 = header, rows 2+ = data)
table.Cells[0, 0].TextString = "My Table Title";
table.Cells[1, 0].TextString = "Name";
table.Cells[1, 1].TextString = "Description";
table.Cells[1, 2].TextString = "Value";
table.Cells[2, 0].TextString = "Item A";
table.Cells[2, 1].TextString = "First item";
table.Cells[2, 2].TextString = "100";
table.GenerateLayout();
btr.AppendEntity(table);
tr.AddNewlyCreatedDBObject(table, true);
tr.Commit();
}
Access cells via table.Cells[row, column] which returns a Cell object.
Setting text:
table.Cells[2, 0].TextString = "Hello";
// Read text back
string text = table.Cells[2, 0].TextString;
// Get text with specific format option
string formatted = table.Cells[2, 0].GetTextString(FormatOption.ForExpression);
Setting a block reference in a cell:
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
ObjectId blockId = bt["MyBlockName"];
table.Cells[2, 1].BlockTableRecordId = blockId;
// Access via Contents collection for multi-content cells
table.Cells[2, 1].Contents[0].BlockTableRecordId = blockId;
table.Cells[2, 1].Contents[0].IsAutoScale = true; // auto-fit block to cell
table.Cells[2, 1].Contents[0].Scale = 1.0; // or set explicit scale
table.Cells[2, 1].Contents[0].Rotation = 0.0; // rotation in radians
Setting a field in a cell:
Field field = new Field("%<\\AcVar Date \\f \"M/d/yyyy\">%");
ObjectId fieldId = db.AddField(field);
tr.AddNewlyCreatedDBObject(field, true);
table.Cells[2, 2].FieldId = fieldId;
// Or via Contents: table.Cells[2, 2].Contents[0].FieldId = fieldId;
Setting typed values:
table.Cells[2, 0].Value = 42.5;
table.Cells[2, 0].SetValue(42.5, ParseOption.SetDefaultFormat);
// Read value back
object val = table.Cells[2, 0].Value;
object valFmt = table.Cells[2, 0].GetValue(FormatOption.ForExpression);
table.Cells[2, 0].ResetValue(); // clear value
Formulas (via Contents):
table.Cells[4, 2].Contents[0].Formula = "=Sum(C3:C5)";
bool hasFormula = table.Cells[4, 2].Contents[0].HasFormula;
Multiple content items per cell:
CellContentsCollection contents = table.Cells[2, 0].Contents;
int count = contents.Count;
contents.Add(); // append new content slot
contents.InsertAt(0); // insert at index
contents.RemoveAt(1); // remove at index
contents.Move(0, 1); // reorder
contents.Clear(); // remove all content
// Access individual content
CellContent c = contents[0];
c.TextString = "Text";
c.TextHeight = 2.5;
c.ContentColor = Color.FromColorIndex(ColorMethod.ByAci, 1); // red
Block attribute values in cells:
string attrVal = table.Cells[2, 1].GetBlockAttributeValue(attDefId);
table.Cells[2, 1].SetBlockAttributeValue(attDefId, "NewValue");
// Or via Contents: table.Cells[2, 1].Contents[0].GetBlockAttributeValue(attDefId);
Formatting is accessed through the CellRange base class (which Cell inherits from), so these properties work on both individual cells and ranges.
Alignment:
table.Cells[2, 0].Alignment = CellAlignment.MiddleCenter;
Text height and style:
table.Cells[2, 0].TextHeight = 2.5;
table.Cells[2, 0].TextStyleId = styleId;
// Per-content text height
table.Cells[2, 0].Contents[0].TextHeight = 3.0;
table.Cells[2, 0].Contents[0].TextStyleId = styleId;
Colors:
using Autodesk.AutoCAD.Colors;
// Content (text) color
table.Cells[2, 0].ContentColor = Color.FromColorIndex(ColorMethod.ByAci, 1); // red
// Background color
table.Cells[2, 0].BackgroundColor = Color.FromColorIndex(ColorMethod.ByAci, 5); // blue
table.Cells[2, 0].IsBackgroundColorNone = false; // must be false to show background
Cell margins (via Borders):
CellBorders borders = table.Cells[2, 0].Borders;
borders.Top.Margin = 1.5;
borders.Bottom.Margin = 1.5;
borders.Left.Margin = 2.0;
borders.Right.Margin = 2.0;
Grid lines (borders):
CellBorder topEdge = table.Cells[2, 0].Borders.Top;
topEdge.LineWeight = LineWeight.LineWeight050;
topEdge.Color = Color.FromColorIndex(ColorMethod.ByAci, 7); // white
topEdge.IsVisible = true;
topEdge.Linetype = linetypeId;
topEdge.LineStyle = GridLineStyle.Single; // Single or Double
topEdge.DoubleLineSpacing = 2.0; // for Double line style
// Available borders: Top, Bottom, Left, Right, Horizontal, Vertical
Content rotation:
table.Cells[2, 0].Contents[0].Rotation = Math.PI / 2; // 90 degrees
Data type and format:
table.Cells[2, 0].DataType = new DataTypeParameter(
Autodesk.AutoCAD.DatabaseServices.DataType.Double,
Autodesk.AutoCAD.DatabaseServices.UnitType.Distance);
table.Cells[2, 0].DataFormat = "%lu2%pr2"; // 2 decimal places
table.Cells[2, 0].Contents[0].DataFormat = "%lu2%pr2";
Cell style and state:
table.Cells[2, 0].Style = "_DATA"; // cell style name: "_TITLE", "_HEADER", "_DATA", or custom
table.Cells[2, 0].State = CellStates.None;
table.Cells[2, 0].ContentLayout = CellContentLayout.Flow;
table.Cells[2, 0].IsMergeAllEnabled = true;
Apply formatting to a range:
CellRange range = CellRange.Create(table, 2, 0, 4, 2); // rows 2-4, cols 0-2
range.Alignment = CellAlignment.MiddleLeft;
range.TextHeight = 2.0;
range.ContentColor = Color.FromColorIndex(ColorMethod.ByAci, 3);
range.BackgroundColor = Color.FromColorIndex(ColorMethod.ByAci, 254);
range.IsBackgroundColorNone = false;
Access counts:
int rowCount = table.Rows.Count;
int colCount = table.Columns.Count;
Insert rows/columns:
table.InsertRows(2, 8.0, 3); // insert 3 rows at index 2, height 8.0
table.InsertColumns(1, 40.0, 2); // insert 2 columns at index 1, width 40.0
// Insert and inherit formatting from an existing row/column
table.InsertRowsAndInherit(3, 2, 1); // insert 1 row at index 3, inherit from row 2
table.InsertColumnsAndInherit(2, 1, 1); // insert 1 col at index 2, inherit from col 1
Delete rows/columns:
table.DeleteRows(2, 1); // delete 1 row starting at index 2
table.DeleteColumns(1, 2); // delete 2 columns starting at index 1
Resize rows/columns:
// Individual row height
table.Rows[2].Height = 12.0;
double minH = table.Rows[2].MinimumHeight;
// Individual column width
table.Columns[1].Width = 60.0;
double minW = table.Columns[1].MinimumWidth;
// Column name
table.Columns[0].Name = "ID";
string name = table.Columns[0].Name;
// Uniform sizing
table.SetRowHeight(8.0); // all rows same height
table.SetColumnWidth(40.0); // all columns same width
// Resize entire table
table.SetSize(10, 5); // resize to 10 rows, 5 columns
table.Height = 200.0; // overall table height
table.Width = 300.0; // overall table width
// Merge a range of cells (topRow, leftCol, bottomRow, rightCol)
CellRange range = CellRange.Create(table, 2, 0, 2, 2);
table.MergeCells(range);
// Unmerge
table.UnmergeCells(range);
// Check if a cell is merged and get its merge range
Cell cell = table.Cells[2, 0];
CellRange mergeRange = cell.GetMergeRange();
bool? isMerged = mergeRange.IsMerged;
Table styles are stored in the TableStyleDictionary. The TableStyle object defines default formatting for title, header, and data rows.
Create a new table style:
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Colors;
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
TableStyle style = new TableStyle();
style.Description = "Custom pipe schedule style";
// Flow direction
style.FlowDirection = FlowDirection.TopToBottom;
// Suppress title/header rows
style.IsTitleSuppressed = false;
style.IsHeaderSuppressed = false;
// Cell margins
style.HorizontalCellMargin = 1.5;
style.VerticalCellMargin = 1.5;
// Text height per row type (RowType: TitleRow=1, HeaderRow=2, DataRow=4)
style.SetTextHeight(3.5, (int)RowType.TitleRow);
style.SetTextHeight(2.5, (int)RowType.HeaderRow);
style.SetTextHeight(2.0, (int)RowType.DataRow);
// Text style per row type
style.SetTextStyle(textStyleId, (int)RowType.DataRow);
// Alignment per row type
style.SetAlignment(CellAlignment.MiddleCenter, (int)RowType.TitleRow);
style.SetAlignment(CellAlignment.MiddleCenter, (int)RowType.HeaderRow);
style.SetAlignment(CellAlignment.MiddleLeft, (int)RowType.DataRow);
// Colors per row type
style.SetColor(Color.FromColorIndex(ColorMethod.ByAci, 7), (int)RowType.TitleRow);
style.SetBackgroundColorNone(true, (int)RowType.DataRow);
// Grid line weights (GridLineType: OuterGridLines=1, InnerGridLines=2, HorizontalGridLines=4,
// VerticalGridLines=8, BottomGridLines=16, All combinations via bitflags)
style.SetGridLineWeight(LineWeight.LineWeight050,
(int)GridLineType.OuterGridLines, (int)RowType.DataRow);
style.SetGridColor(Color.FromColorIndex(ColorMethod.ByAci, 7),
(int)GridLineType.InnerGridLines, (int)RowType.DataRow);
style.SetGridVisibility(true,
(int)GridLineType.OuterGridLines, (int)RowType.DataRow);
// Per cell-style margins
style.SetMargin(CellMargins.Left, 2.0, "_DATA");
style.SetMargin(CellMargins.Right, 2.0, "_DATA");
style.SetMargin(CellMargins.Top, 1.0, "_HEADER");
style.SetMargin(CellMargins.Bottom, 1.0, "_HEADER");
// Post to database
ObjectId styleId = style.PostTableStyleToDatabase(db, "MyTableStyle");
tr.AddNewlyCreatedDBObject(style, true);
tr.Commit();
}
Apply a table style:
DBDictionary styleDict = (DBDictionary)tr.GetObject(
db.TableStyleDictionaryId, OpenMode.ForRead);
if (styleDict.Contains("MyTableStyle"))
{
table.TableStyle = styleDict.GetAt("MyTableStyle");
}
// Read current style name (read-only)
string styleName = table.TableStyleName;
CellAlignment: TopLeft=1, TopCenter=2, TopRight=3, MiddleLeft=4, MiddleCenter=5, MiddleRight=6, BottomLeft=7, BottomCenter=8, BottomRight=9
FlowDirection: NotSet=0, LeftToRight=1, RightToLeft=2, TopToBottom=3, BottomToTop=4, ByStyle=5
TableBreakOptions (flags): None=0, EnableBreaking=1, RepeatTopLabels=2, RepeatBottomLabels=4, AllowManualPositions=8, AllowManualHeights=16
TableBreakFlowDirection: Right=1, DownOrUp=2, Left=4
GridLineStyle: Single, Double
GenerateLayout() after populating the table and before committing. Without it the table may not render correctly.SetSize(rows, cols) replaces the old NumRows/NumColumns setters which are obsolete. Use Rows.Count and Columns.Count to read the current size.Cells[row, col] API rather than the old method-based API (e.g., SetTextString(row, col, text) is obsolete). The old methods still work but are marked [Obsolete].Table inherits from BlockReference, so Position sets the insertion point. The table grows downward from this point when FlowDirection is TopToBottom.CellRange properties are nullable (e.g., Alignment is CellAlignment?). When reading a range that spans cells with different values, the property returns null.ForWrite before modifying cells, rows, columns, or table properties. Open it via tr.GetObject(tableId, OpenMode.ForWrite).RecomputeTableBlock(true) forces a visual update if the table appearance is stale after programmatic changes. Usually GenerateLayout() is sufficient.SuppressRegenerateTable(true) can improve performance when making many changes in a batch. Call SuppressRegenerateTable(false) when done, then GenerateLayout().IsAutoScale = true to fit the block to the cell, or set Scale manually. The BlockTableRecordId must reference a valid block definition.int rowTypes as a bitmask cast from RowType (TitleRow=1, HeaderRow=2, DataRow=4). Combine with bitwise OR for multiple row types."_TITLE", "_HEADER", "_DATA" are the built-in names. Custom cell styles can be added to a TableStyle.acad-fields — field content in table cellsacad-mtext — MText formatting in cell textacad-blocks — block references as cell contentacad-layers — layer assignment for table entities