How to Add Tables in Word Documents Using OfficeCLI: A Complete Guide

OfficeCLI creates Word tables by emitting OpenXML <w:tbl> elements through the add sub-command with the --type table flag, allowing you to specify dimensions, borders, column widths, and content via property arguments.

OfficeCLI is an open-source command-line tool for manipulating Microsoft Office documents without requiring the desktop applications. In the iOfficeAI/OfficeCLI repository, the Word table functionality is implemented in WordHandler.Add.Table.cs, which constructs valid OpenXML table structures and inserts them into .docx files.

Understanding the Table Architecture

The table creation process follows a structured pipeline defined in WordHandler.Add.Table.cs (lines 45-78). When you execute an add command targeting a Word document, the CLI parses your arguments, routes them to WordHandler.AddTable, and builds a complete <w:tbl> element with associated grid properties and rows.

Command Parsing and Routing

The CLI entry point accepts commands in the format:

officecli add <file> <path> --type table --prop <key>=<value>

The --type table flag routes the request to WordHandler.AddTable in src/officecli/Handlers/Word/WordHandler.Add.Table.cs (lines 45-66). This method receives:

  • The target parent element (/body or a specific table cell path)
  • An optional insertion index
  • A dictionary of properties for table configuration

Default Table Borders

Unless you specify skipDefaultBorders=true, the emitter automatically seeds six default borders (top, left, bottom, right, inside-horizontal, inside-vertical) to ensure newly created tables have a complete border set. This logic resides in lines 48-55 of WordHandler.Add.Table.cs.

Table Properties Reference

The WordHandler.Add.Table.cs implementation (lines 92-132) interprets a comprehensive set of table-level properties through a dictionary walker that consumes known keys and falls back to generic attribute setters for unknown properties.

Dimensions and Layout

Control the table structure with these properties:

  • rows and cols (or columns) – Define table dimensions explicitly
  • colWidths – Comma-separated list of column widths in twips or with units (e.g., 2500,2500,1500)
  • gridCols – Overrides the implicit grid column count
  • width – Total table width
  • indent – Table indentation
  • cellSpacing – Spacing between cells
  • layout – Table layout algorithm (fixed or autofit)

Borders and Styling

Customize visual presentation:

  • border.* – Per-side border overrides (e.g., border.top, border.left)
  • border.all – Applies uniform borders to all sides; use this to wipe defaults first
  • style, tblStyle, or tblStyleId – Apply named table styles from the document
  • padding.* – Cell padding settings (e.g., padding=80)

Banding and Accessibility

Enhance table semantics:

  • direction or bidi – Set RTL rendering (injects <w:bidiVisual/>)
  • caption – Table caption text
  • description – Table description for accessibility
  • rowBandSize and colBandSize – Controls banding rows/columns for styled tables

Grid Construction Logic

In WordHandler.Add.Table.cs (lines 149-183), the grid construction logic determines column widths:

If you provide colWidths, the handler generates a <w:tblGrid> containing matching <w:gridCol> entries. Without explicit widths, the grid infers dimensions from the section width and column count, calculating automatic widths that fit the available page space.

Row and Cell Creation

The implementation iterates over the computed row and column counts to create <w:tr> (table row) and <w:tc> (table cell) elements. According to lines 88-115 in WordHandler.Add.Table.cs, each cell receives a paragraph containing the appropriate text content. If you provide no data, cells contain empty paragraphs. When using the data property, the handler parses CSV-like shorthand to populate cells automatically.

Insertion and Positioning

After construction, the table inserts at the specified location (lines 200-207). If you provide an explicit index, the table inserts at that position within the parent element; otherwise, it appends to the end. This ensures precise control over document structure when adding multiple tables.

RTL Support and Auto-Direction

When the surrounding document section uses RTL (right-to-left) layout and you do not explicitly set a direction, the handler automatically injects <w:bidiVisual/> to mirror column order for RTL reading direction (lines 274-282). You can override this by setting direction=ltr or direction=rtl explicitly.

Practical Examples

The following commands demonstrate the table creation capabilities using the officecli interface.

Basic Table Creation

Create a simple 3×4 table with default borders:

officecli add document.docx /body --type table \
  --prop rows=3 --prop cols=4

Advanced Styling

Create a table with explicit borders, column widths, and fixed layout:

officecli add document.docx /body --type table \
  --prop rows=3 --prop cols=4 \
  --prop "border.all=single;8;2E74B5" \
  --prop "colWidths=2500,2500,2500,2500" \
  --prop "layout=fixed" \
  --prop "padding=80"

Modify existing table borders:

officecli set document.docx '/body/tbl[1]' --prop "border.top=double;8;1F3864"
officecli set document.docx '/body/tbl[1]' --prop "border.bottom=double;8;1F3864"

Inline Data Shorthand

Use the data property to create and populate a table simultaneously:

officecli add document.docx /body --type table \
  --prop "data=Region,Q1,Q2;North,120,150;South,90,110" \
  --prop "border.all=single;4;808080"

The rows and columns are inferred from the CSV-like data string.

RTL Tables

Create a table for right-to-left languages:

officecli add document.docx /body --type table \
  --prop rows=2 --prop cols=2 \
  --prop "direction=rtl" \
  --prop "border.all=single;8;C00000"

Summary

  • Entry Point: Use officecli add <file> <path> --type table to invoke the WordHandler.AddTable method in WordHandler.Add.Table.cs
  • Border Defaults: Tables receive six default borders automatically unless skipDefaultBorders=true is set
  • Property Parsing: Supports extensive properties including rows, cols, colWidths, border.*, style, and direction
  • Grid Logic: Generates <w:tblGrid> elements based on explicit widths or inferred from section dimensions
  • Data Population: Use the data property for CSV-like shorthand to define content during creation
  • RTL Support: Automatic <w:bidiVisual/> injection for RTL sections with manual override capability

Frequently Asked Questions

How do I specify individual column widths when adding a table?

Use the colWidths property with a comma-separated list of values. According to the implementation in WordHandler.Add.Table.cs (lines 149-183), these values can be specified in twips or with units, and the handler generates corresponding <w:gridCol> elements for each width specified.

Can I add data to the table during creation, or must I insert cells separately?

You can populate the table during creation using the data property. Pass a CSV-like string with semicolon-separated rows, such as --prop "data=Header1,Header2;Row1Col1,Row1Col2". The handler automatically sizes the table based on the data structure and fills each cell with the corresponding text.

What happens if I don't specify border properties?

If you omit border specifications, the handler automatically applies six default borders (top, left, bottom, right, inside-horizontal, inside-vertical) to ensure the table is visible. To create a borderless table, you must explicitly set skipDefaultBorders=true and avoid adding border properties.

How does OfficeCLI handle right-to-left (RTL) table layout?

When the document section uses RTL formatting and you do not specify a direction explicitly, the code in WordHandler.Add.Table.cs (lines 274-282) automatically injects <w:bidiVisual/> to mirror column order appropriately. You can override this behavior by setting direction=rtl or direction=ltr explicitly in the properties.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →