Creating a custom AutoCAD table style using .NET
The question of how to define a new table style programmatically has come up a couple of times over the last week or so, so this post shows how to approach this. I've used the code from this previous post as a basis for this post's.
The important thing to know is that TableStyle objects are stored in a special dictionary, which can be accessed via a Database's TableStyleDictionaryId property. This ObjectId property allows you to access the dictionary, from which you can query the contents, determine whether your style exists and add a new one if it doesn't. The code to specify the colour and formatting of the table style is reasonably straightforward.
Here's some C# code to define a new "Garish Table Style" with a red header/title area, yellow data area and magenta text throughout (better put on your sunglasses before running it... :-):
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Colors;
namespace TableAndStyleCreation
{
public class Commands
{
[CommandMethod("CTWS")]
static public void CreateTableWithStyle()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptPointResult pr =
ed.GetPoint("\nEnter table insertion point: ");
if (pr.Status == PromptStatus.OK)
{
Transaction tr =
doc.TransactionManager.StartTransaction();
using (tr)
{
// First let us create our custom style,
// if it doesn't exist
const string styleName = "Garish Table Style";
ObjectId tsId = ObjectId.Null;
DBDictionary sd =
(DBDictionary)tr.GetObject(
db.TableStyleDictionaryId,
OpenMode.ForRead
);
// Use the style if it already exists
if (sd.Contains(styleName))
{
tsId = sd.GetAt(styleName);
}
else
{
// Otherwise we have to create it
TableStyle ts = new TableStyle();
// Make the header area red
ts.SetBackgroundColor(
Color.FromColorIndex(ColorMethod.ByAci, 1),
(int)(RowType.HeaderRow | RowType.TitleRow)
);
// And the data area yellow
ts.SetBackgroundColor(
Color.FromColorIndex(ColorMethod.ByAci, 2),
(int)RowType.DataRow
);
// With magenta text everywhere (yeuch :-)
ts.SetColor(
Color.FromColorIndex(ColorMethod.ByAci, 6),
(int)(RowType.HeaderRow |
RowType.TitleRow |
RowType.DataRow)
);
// Add our table style to the dictionary
// and to the transaction
sd.UpgradeOpen();
tsId = sd.SetAt(styleName, ts);
tr.AddNewlyCreatedDBObject(ts, true);
sd.DowngradeOpen();
}
BlockTable bt =
(BlockTable)tr.GetObject(
doc.Database.BlockTableId,
OpenMode.ForRead
);
Table tb = new Table();
// Use our table style
if (tsId == ObjectId.Null)
// This should not happen, unless the
// above logic changes
tb.TableStyle = db.Tablestyle;
else
tb.TableStyle = tsId;
tb.NumRows = 5;
tb.NumColumns = 3;
tb.SetRowHeight(3);
tb.SetColumnWidth(15);
tb.Position = pr.Value;
// Create a 2-dimensional array
// of our table contents
string[,] str = new string[5, 4];
str[0, 0] = "Part No.";
str[0, 1] = "Name ";
str[0, 2] = "Material ";
str[1, 0] = "1876-1";
str[1, 1] = "Flange";
str[1, 2] = "Perspex";
str[2, 0] = "0985-4";
str[2, 1] = "Bolt";
str[2, 2] = "Steel";
str[3, 0] = "3476-K";
str[3, 1] = "Tile";
str[3, 2] = "Ceramic";
str[4, 0] = "8734-3";
str[4, 1] = "Kean";
str[4, 2] = "Mostly water";
// Use a nested loop to add and format each cell
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 3; j++)
{
tb.SetTextHeight(i, j, 1);
tb.SetTextString(i, j, str[i, j]);
tb.SetAlignment(i, j, CellAlignment.MiddleCenter);
}
}
tb.GenerateLayout();
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite
);
btr.AppendEntity(tb);
tr.AddNewlyCreatedDBObject(tb, true);
tr.Commit();
}
}
}
}
}
Here's what happens when we load the module and run the CTWS command, selecting a location for our "garish" table:
And if we launch AutoCAD's TABLESTYLE command we can see our custom style in the list:
Update
A further post on this topic has now been published.

Subscribe via RSS
This sample is most appreciated by me - I have been really ... by the tables so far :)
The sample works as expected. But I have some questions that you can help me out with (I use managed C++):
(1) After creating the table, it doesn't have any style associated with it, its style id is null - we have to set a style to the table to get "expected results", right?
(2) I tried placing the table in the paper space in the layout, and it didn't show up. It shows up properly in the model space, and the modelspace viewport in the layout. How can I fix this in the sample?
Thanks for the sample!
Gagan
==============
Posted by: Gagan | December 04, 2008 at 07:58 PM
Kean, Please ignore my question (2) in the previous post! I should have thought a bit before typing it!
Thanks,
Gagan
==============
Posted by: Gagan | December 04, 2008 at 09:44 PM
Hi Kean,
I copied and run the code, but the result is not like yours. The most confused me is the title, in my table there were three columns showed "Name" and "Material". How can you hide these two columns and make the "Part No" center?
Posted by: Travor | January 04, 2009 at 10:39 AM
I merged the first row's three columns to hide these two columns and make the "Part No" center, this can make my result as yours. But I didn't see any merge code in this example. Is there any other way to do that?
To Gagan:
Yse, after you create a table, the TableStyle'id is null, but it has a default table style, which you can see in "TABLESTYLE" command in AuotCAD, it's name is "default". This id will not assigned until you add the new table object to blocktable and commit the transaction.
Posted by: Travor | January 09, 2009 at 08:41 AM
Travor,
Actually, I now realise I didn't look very closely at the contents of the generated table when I put this post together...
I didn't use merge code - the 0,0 cell ends up being used as the title (as I didn't suppress it).
I'll post a new entry with the updated code - email me if you need it sooner.
Regards,
Kean
Posted by: Kean Walmsley | January 14, 2009 at 04:46 PM