Creating Table Elements in .dgn Files

Andrew Ryabinin

July 13, 2017

Table elements for .dgn files are supported by Bentley® MicroStation V8i Connect Edition and later. The structure and purpose of .dgn table elements are similar to .dwg table elements. A table is a set of cells arranged in rows and columns. The cells in a table are separated by gridlines, and .dgn table element cells can contain only text data.

To create a .dgn table element:

1) Add a table element to the .dgn model or to a shared cell definition if it is possible, and initialize it using the function initTableDefaults(). A table element uses text styles to initialize its defaults and to operate with cell text data. But it stores only text style indexes. Therefore, it needs the .dgn database to have access to the text style table. Also it needs to convert Units of Resolution (UORs) to a working units scale factor (text styles store all its data in UORs, but if you plan to use a table element as part of a .dgn model, it must operate with model working units).

OdDgTableElementPtr pTableElement = OdDgTableElement::createObject();
m_pModel3d->addElement( pTableElement );
pTableElement->initTableDefaults();

2) After initialization, set the table body text style. It is necessary to set the default row height, default column width, minimal table cell width and height, and default table cell margin offsets.

OdDgTextStyleTableRecordPtr pTableTextStyle = pTextStyleTable->getDefaultData();
pTableTextStyle->setName(L"TableTextStyle");
pTableTextStyle->setTextHeight( 0.1 * dScaleToUORs );
pTableTextStyle->setTextWidth( 0.1 * dScaleToUORs );
pTableTextStyle->setFontEntryId( pFontTable->getFont("Arial")->getNumber() );
pTableTextStyle->setColorIndex(250);
pTextStyleTable->add( pTableTextStyle );
pTableElement->setBodyTextStyle( pTableTextStyle->getEntryId() );

3) Add table columns and table rows. Row and column measurements are initialized with default data after creation.

pTableElement->addColumn();
…
pTableElement->addColumn();
pTableElement->addRow();
…
pTableElement->addRow();

4) Modify column and row measurements. Here is a sample of modifying row and column measurements:

pTableElement->getRow(1)->setHeight( 0.2 * minor );
…
pTableElement->getColumn(1)->setWidth( 0.15 * major );

5) Merge table cells. Several table cells can be merged into one large cell. There are three rules for cell merging:

  • Merges can't intersect themselves.
  • Only rectangular cell regions can be merged.
  • The content of the merge is the content in the top left (base) cell.
OdDgTableElementMerge titleMerge;
titleMerge.setBaseRowIndex(0);
titleMerge.setBaseColumnIndex(0);
titleMerge.setRowCount(1);
titleMerge.setColumnCount(5);

pTableElement->addMerge( titleMerge );

6) Set table fill colors. There are two types of table fills. First, every cell can be filled.

pTableElement->getCell(1,4)->setFillColor(32);

Also, odd and even fill colors can be applied to body rows of the table. (The table element contains rows of different types. By default, all rows are body rows, but it is possible to set a non-zero number of title rows, header rows, and footer rows.)

pTableElement->setOddFillColor( 1 );
pTableElement->setOddFillColorFlag(true);
pTableElement->setEvenFillColor( 2 );
pTableElement->setEvenFillColorFlag(true);

7) Set cell content. Table element cells can contain only text data. There are two ways to set cell content:

  • Easy way: Set simple text using the function “setCellText( const OdString& strText )”. The function creates a text node with a cell text style and adds one text element with a required string.
  • Manual way: Set multiline text with different colors, sizes, fonts, etc., create a text node and fill it with text elements, and then set it using the setCellText(…) function.
OdDgTextNode3dPtr pMTextNode = OdDgTextNode3d::createObject();
OdDgText3dPtr pTextLine1 = OdDgText3d::createObject();
OdDgText3dPtr pTextLine2 = OdDgText3d::createObject();
…
pMTextNode->add( pTextLine1 );
pMTextNode->add( pTextLine2 );
…
pMTextNode->setDatabaseDefaults(m_pModel3d->database(), true);
pMTextNode->applyTextStyle( pMextStyle->elementId() );
pMTextNode->setJustification( OdDg::kCenterCenter );
pMTextNode->setLineSpacing(0.09);
pMTextNode->setLineSpacingType( OdDgTextExtendedProperties::kExact );
pTextLine1->applyTextStyle( pMextStyle->elementId() );
pTextLine2->applyTextStyle( pMextStyle->elementId() );
…
pTextLine1->setText(L"Multiline Text:");
pTextLine1->setCrCount(1);
pTextLine2->setText(L"- Line 1.");
pTextLine2->setItalics(true);
pTextLine2->setCrCount(1);
…
pTableElement->getCell(3,2)->setCellText( pMTextNode );

8) You can also format the text position, text rotation, cell margin type, and cell borders.

// Set text alignment “Center, Middle”
pTableElement->getCell(1,1)->setTextAlignment(OdDgTableCellElement::kCenterMiddle);
// modify cell borders.
OdDgTableCellSymbology borderData;
borderData.setColorIndex(3);
borderData.setLineStyle(2);
borderData.setLineWeight(3);
borderData.setLineVisibility(true);

pTableElement->getCell(3,2)->setTopBorder(borderData);
pTableElement->getCell(3,2)->setBottomBorder(borderData);
pTableElement->getCell(3,2)->setLeftBorder(borderData);
pTableElement->getCell(3,2)->setRightBorder(borderData);

All code in this article is from the ExDgnCreate sample. See it to get more information about the creation of tables.