Working with WordprocessingML tables
Tables are stored in the main document XML as <w:tbl/>. Rows are <w:tr/>, cells are <w:tc/>, and cell content is usually paragraphs.
Tables are block-level content, arranged as rows and columns. A table can contain paragraph content and other block-level content inside cells.
Table markup
<w:tbl>
<w:tblPr>
<w:tblStyle w:val="TableGrid"/>
<w:tblW w:w="5000" w:type="pct"/>
</w:tblPr>
<w:tblGrid>
<w:gridCol/>
<w:gridCol/>
<w:gridCol/>
</w:tblGrid>
<w:tr>
<w:tc>
<w:tcPr/>
<w:p><w:r><w:t>1</w:t></w:r></w:p>
</w:tc>
<w:tc>
<w:tcPr/>
<w:p><w:r><w:t>2</w:t></w:r></w:p>
</w:tc>
<w:tc>
<w:tcPr/>
<w:p><w:r><w:t>3</w:t></w:r></w:p>
</w:tc>
</w:tr>
</w:tbl>
w:tblPr is required for a w:tbl in the generated schema and defines table-wide properties, such as style and width. w:tblGrid is optional and defines grid layout through w:gridCol children. Each w:tr can have row properties, and each w:tc can optionally include w:tcPr for cell-specific settings such as width, borders, margins, and vertical alignment.
Rust workflow
The document text helper includes text found inside table cells:
#![allow(unused)] fn main() { pub fn get_document_text(path: &Path) -> Result<Vec<String>, Box<dyn std::error::Error>> { let document = WordprocessingDocument::new_from_file_with_settings(path, lazy_settings())?; let main_part = document.main_document_part()?; let xml = main_part.data_as_str(&document)?.unwrap_or_default(); Ok(extract_text_values(xml)) } }
For table-specific edits, parse <w:tbl/>, <w:tr/>, and <w:tc/> boundaries so updates do not affect unrelated body paragraphs.
In ooxmlsdk, generated schema types include Table, TableProperties, TableGrid, GridColumn, TableRow, TableRowProperties, TableCell, TableCellProperties, TableStyle, TableWidth, and TableBorders.