Skip to main content

Table

Struct Table 

Source
pub struct Table {
    pub rows: Vec<TableRow>,
    pub column_widths: Vec<u32>,
    pub border_color: Option<String>,
    pub alignment: Option<Alignment>,
    pub indent_twips: Option<u32>,
    pub style_id: Option<String>,
}
Expand description

A table: a sequence of rows.

Column count is always derived from the widest row (accounting for TableCell.horizontal_span), never stored explicitly. Column WIDTHS default to equal, fixed widths (see writer.rs’s DEFAULT_COLUMN_WIDTH_TWIPS) unless column_widths overrides them.

Fields§

§rows: Vec<TableRow>

The rows that make up this table, in order.

§column_widths: Vec<u32>

Per-column preferred widths, in twips (twentieths of a point, w:gridCol/@w’s own unit — see Run.character_spacing’s doc comment for the same “expose the raw unit, no conversion” convention used throughout this crate), one entry per grid column in order. Left empty (the default) to keep the writer’s previous behavior: every column gets the same fixed default width. When non-empty, entries beyond the table’s real column count are simply unused, and a real column count exceeding column_widths.len() falls back to the default width for the remaining columns — not validated or required to match exactly, same “best-effort, not strictly enforced” policy as Paragraph.numbering_id/style_id referencing a declaration that may or may not actually exist.

Setting this also makes the writer emit <w:tblLayout w:type="fixed"/> (CT_TblLayoutType’s two values are fixed/ autofit, autofit being Word’s default when the element is omitted entirely). This matters a lot in practice: under the default autofit layout, Word treats tblGrid’s widths as mere starting suggestions and actively reflows columns based on cell content (“the presence of long non-breaking content can widen a column, proportionally shrinking the others” — ECMA-376’s own worked example for ST_TblLayoutType) — so explicit widths would often be silently overridden without fixed layout forcing Word to honor them regardless of content.

§border_color: Option<String>

The color of the table’s own border lines (w:tblBorders‘s sides’ color attribute, a plain 6-digit RGB hex string), or None to use the fixed "auto" (black) this crate has always used. Overrides all six sides (top/left/bottom/right/insideH/insideV) uniformly — WordprocessingML allows each side its own independent color, but a single uniform color covers the common case and matches the fixed-appearance convention already used for Paragraph.border/Run.text_border/TableCell.border.

§alignment: Option<Alignment>

The table’s own horizontal alignment/positioning on the page (w:tblPr/w:jc, CT_JcTable) — where the whole table sits relative to the page margins, distinct from Paragraph.alignment (which aligns text within a paragraph). None leaves it unspecified (Word’s default, effectively left-aligned). Reuses Alignment even though CT_JcTable’s own enumeration (ST_JcTable) is actually a different, smaller type than ST_Jc (no distribute, but it does still cover left/center/right/both) — the values this crate models for Alignment (Left/Center/Right/Justify) all happen to also be valid ST_JcTable values, so sharing the type avoids a near-duplicate enum.

§indent_twips: Option<u32>

The table’s indentation from the leading margin, in twips (w:tblPr/w:tblInd, CT_TblWidth, always written with w:type="dxa"), or None to leave it unspecified (no extra indentation).

§style_id: Option<String>

The id of a table-type named style to apply (w:tblPr/w:tblStyle), or None. Unlike Paragraph.style_id/Run.style_id, this crate does not model declaring a table style in Document.styles (CT_Style’s table-kind styles carry their own rich conditional formatting — CT_TblStylePr per table region: first row, banding, corner cells. — a large surface with no real need seen yet, matching the scope reduction already applied to StyleKind, which only models paragraph/character). Referencing one of Word’s built-in table style ids (e.g. "TableGrid", "LightList-Accent1") still works perfectly well without a local declaration, the same way referencing a built-in paragraph style like "Heading1" does — Word resolves those from its own built-in style set when the document doesn’t declare them itself.

Implementations§

Source§

impl Table

Source

pub fn new() -> Table

Creates an empty table.

Examples found in repository?
examples/docx_tables.rs (line 16)
13fn main() -> office_toolkit::Result<()> {
14    let path = output_path("docx_tables.docx");
15
16    let plain_table = Table::new()
17        .with_row(
18            TableRow::new()
19                .with_cell(TableCell::with_text("Name"))
20                .with_cell(TableCell::with_text("Score")),
21        )
22        .with_row(
23            TableRow::new()
24                .with_cell(TableCell::with_text("Alice"))
25                .with_cell(TableCell::with_text("92")),
26        )
27        .with_row(
28            TableRow::new()
29                .with_cell(TableCell::with_text("Bob"))
30                .with_cell(TableCell::with_text("87")),
31        );
32
33    let merged_table = Table::new()
34        .with_row(
35            TableRow::new()
36                .with_repeat_as_header_row(true)
37                .with_cell(TableCell::with_text("Quarterly report").with_horizontal_span(3)),
38        )
39        .with_row(
40            TableRow::new()
41                .with_cell(
42                    TableCell::with_text("Region").with_vertical_merge(VerticalMerge::Restart),
43                )
44                .with_cell(TableCell::with_text("Q1"))
45                .with_cell(TableCell::with_text("Q2")),
46        )
47        .with_row(
48            TableRow::new()
49                .with_cell(TableCell::new().with_vertical_merge(VerticalMerge::Continue))
50                .with_cell(TableCell::with_text("1,200"))
51                .with_cell(TableCell::with_text("1,350")),
52        );
53
54    let styled_table = Table::new()
55        .with_column_widths(vec![3_000, 3_000, 3_000])
56        .with_border_color("2E74B5")
57        .with_indent_twips(360)
58        .with_row(
59            TableRow::new()
60                .with_height_twips(500)
61                .with_cell(TableCell::with_text("Header A").with_shading_color("D9E2F3"))
62                .with_cell(TableCell::with_text("Header B").with_shading_color("D9E2F3"))
63                .with_cell(TableCell::with_text("Header C").with_shading_color("D9E2F3")),
64        )
65        .with_row(
66            TableRow::new()
67                .with_cant_split(true)
68                .with_cell(TableCell::with_text("1").with_border(true))
69                .with_cell(TableCell::with_text("2").with_border(true))
70                .with_cell(TableCell::with_text("3").with_border(true)),
71        );
72
73    let document = Document::new()
74        .with_paragraph(heading("A plain table", false))
75        .with_table(plain_table)
76        .with_paragraph(heading(
77            "Merged cells: a spanning header row and a vertically merged column",
78            true,
79        ))
80        .with_table(merged_table)
81        .with_paragraph(heading(
82            "Column widths, border color, shading and indentation",
83            true,
84        ))
85        .with_table(styled_table);
86
87    document.save_to_file(&path)?;
88    println!("Wrote {}", path.display());
89    Ok(())
90}
Source

pub fn with_row(self, row: TableRow) -> Table

Appends a row and returns the table for chaining.

Examples found in repository?
examples/docx_tables.rs (lines 17-21)
13fn main() -> office_toolkit::Result<()> {
14    let path = output_path("docx_tables.docx");
15
16    let plain_table = Table::new()
17        .with_row(
18            TableRow::new()
19                .with_cell(TableCell::with_text("Name"))
20                .with_cell(TableCell::with_text("Score")),
21        )
22        .with_row(
23            TableRow::new()
24                .with_cell(TableCell::with_text("Alice"))
25                .with_cell(TableCell::with_text("92")),
26        )
27        .with_row(
28            TableRow::new()
29                .with_cell(TableCell::with_text("Bob"))
30                .with_cell(TableCell::with_text("87")),
31        );
32
33    let merged_table = Table::new()
34        .with_row(
35            TableRow::new()
36                .with_repeat_as_header_row(true)
37                .with_cell(TableCell::with_text("Quarterly report").with_horizontal_span(3)),
38        )
39        .with_row(
40            TableRow::new()
41                .with_cell(
42                    TableCell::with_text("Region").with_vertical_merge(VerticalMerge::Restart),
43                )
44                .with_cell(TableCell::with_text("Q1"))
45                .with_cell(TableCell::with_text("Q2")),
46        )
47        .with_row(
48            TableRow::new()
49                .with_cell(TableCell::new().with_vertical_merge(VerticalMerge::Continue))
50                .with_cell(TableCell::with_text("1,200"))
51                .with_cell(TableCell::with_text("1,350")),
52        );
53
54    let styled_table = Table::new()
55        .with_column_widths(vec![3_000, 3_000, 3_000])
56        .with_border_color("2E74B5")
57        .with_indent_twips(360)
58        .with_row(
59            TableRow::new()
60                .with_height_twips(500)
61                .with_cell(TableCell::with_text("Header A").with_shading_color("D9E2F3"))
62                .with_cell(TableCell::with_text("Header B").with_shading_color("D9E2F3"))
63                .with_cell(TableCell::with_text("Header C").with_shading_color("D9E2F3")),
64        )
65        .with_row(
66            TableRow::new()
67                .with_cant_split(true)
68                .with_cell(TableCell::with_text("1").with_border(true))
69                .with_cell(TableCell::with_text("2").with_border(true))
70                .with_cell(TableCell::with_text("3").with_border(true)),
71        );
72
73    let document = Document::new()
74        .with_paragraph(heading("A plain table", false))
75        .with_table(plain_table)
76        .with_paragraph(heading(
77            "Merged cells: a spanning header row and a vertically merged column",
78            true,
79        ))
80        .with_table(merged_table)
81        .with_paragraph(heading(
82            "Column widths, border color, shading and indentation",
83            true,
84        ))
85        .with_table(styled_table);
86
87    document.save_to_file(&path)?;
88    println!("Wrote {}", path.display());
89    Ok(())
90}
Source

pub fn with_column_widths(self, column_widths: Vec<u32>) -> Table

Sets this table’s per-column preferred widths (in twips, one entry per grid column) and returns it for chaining. See column_widths’s doc comment for how this also switches the table to a fixed (rather than autofit) layout.

Examples found in repository?
examples/docx_tables.rs (line 55)
13fn main() -> office_toolkit::Result<()> {
14    let path = output_path("docx_tables.docx");
15
16    let plain_table = Table::new()
17        .with_row(
18            TableRow::new()
19                .with_cell(TableCell::with_text("Name"))
20                .with_cell(TableCell::with_text("Score")),
21        )
22        .with_row(
23            TableRow::new()
24                .with_cell(TableCell::with_text("Alice"))
25                .with_cell(TableCell::with_text("92")),
26        )
27        .with_row(
28            TableRow::new()
29                .with_cell(TableCell::with_text("Bob"))
30                .with_cell(TableCell::with_text("87")),
31        );
32
33    let merged_table = Table::new()
34        .with_row(
35            TableRow::new()
36                .with_repeat_as_header_row(true)
37                .with_cell(TableCell::with_text("Quarterly report").with_horizontal_span(3)),
38        )
39        .with_row(
40            TableRow::new()
41                .with_cell(
42                    TableCell::with_text("Region").with_vertical_merge(VerticalMerge::Restart),
43                )
44                .with_cell(TableCell::with_text("Q1"))
45                .with_cell(TableCell::with_text("Q2")),
46        )
47        .with_row(
48            TableRow::new()
49                .with_cell(TableCell::new().with_vertical_merge(VerticalMerge::Continue))
50                .with_cell(TableCell::with_text("1,200"))
51                .with_cell(TableCell::with_text("1,350")),
52        );
53
54    let styled_table = Table::new()
55        .with_column_widths(vec![3_000, 3_000, 3_000])
56        .with_border_color("2E74B5")
57        .with_indent_twips(360)
58        .with_row(
59            TableRow::new()
60                .with_height_twips(500)
61                .with_cell(TableCell::with_text("Header A").with_shading_color("D9E2F3"))
62                .with_cell(TableCell::with_text("Header B").with_shading_color("D9E2F3"))
63                .with_cell(TableCell::with_text("Header C").with_shading_color("D9E2F3")),
64        )
65        .with_row(
66            TableRow::new()
67                .with_cant_split(true)
68                .with_cell(TableCell::with_text("1").with_border(true))
69                .with_cell(TableCell::with_text("2").with_border(true))
70                .with_cell(TableCell::with_text("3").with_border(true)),
71        );
72
73    let document = Document::new()
74        .with_paragraph(heading("A plain table", false))
75        .with_table(plain_table)
76        .with_paragraph(heading(
77            "Merged cells: a spanning header row and a vertically merged column",
78            true,
79        ))
80        .with_table(merged_table)
81        .with_paragraph(heading(
82            "Column widths, border color, shading and indentation",
83            true,
84        ))
85        .with_table(styled_table);
86
87    document.save_to_file(&path)?;
88    println!("Wrote {}", path.display());
89    Ok(())
90}
Source

pub fn with_border_color(self, border_color: impl Into<String>) -> Table

Sets this table’s border color and returns it for chaining. See border_color’s doc comment.

Examples found in repository?
examples/docx_tables.rs (line 56)
13fn main() -> office_toolkit::Result<()> {
14    let path = output_path("docx_tables.docx");
15
16    let plain_table = Table::new()
17        .with_row(
18            TableRow::new()
19                .with_cell(TableCell::with_text("Name"))
20                .with_cell(TableCell::with_text("Score")),
21        )
22        .with_row(
23            TableRow::new()
24                .with_cell(TableCell::with_text("Alice"))
25                .with_cell(TableCell::with_text("92")),
26        )
27        .with_row(
28            TableRow::new()
29                .with_cell(TableCell::with_text("Bob"))
30                .with_cell(TableCell::with_text("87")),
31        );
32
33    let merged_table = Table::new()
34        .with_row(
35            TableRow::new()
36                .with_repeat_as_header_row(true)
37                .with_cell(TableCell::with_text("Quarterly report").with_horizontal_span(3)),
38        )
39        .with_row(
40            TableRow::new()
41                .with_cell(
42                    TableCell::with_text("Region").with_vertical_merge(VerticalMerge::Restart),
43                )
44                .with_cell(TableCell::with_text("Q1"))
45                .with_cell(TableCell::with_text("Q2")),
46        )
47        .with_row(
48            TableRow::new()
49                .with_cell(TableCell::new().with_vertical_merge(VerticalMerge::Continue))
50                .with_cell(TableCell::with_text("1,200"))
51                .with_cell(TableCell::with_text("1,350")),
52        );
53
54    let styled_table = Table::new()
55        .with_column_widths(vec![3_000, 3_000, 3_000])
56        .with_border_color("2E74B5")
57        .with_indent_twips(360)
58        .with_row(
59            TableRow::new()
60                .with_height_twips(500)
61                .with_cell(TableCell::with_text("Header A").with_shading_color("D9E2F3"))
62                .with_cell(TableCell::with_text("Header B").with_shading_color("D9E2F3"))
63                .with_cell(TableCell::with_text("Header C").with_shading_color("D9E2F3")),
64        )
65        .with_row(
66            TableRow::new()
67                .with_cant_split(true)
68                .with_cell(TableCell::with_text("1").with_border(true))
69                .with_cell(TableCell::with_text("2").with_border(true))
70                .with_cell(TableCell::with_text("3").with_border(true)),
71        );
72
73    let document = Document::new()
74        .with_paragraph(heading("A plain table", false))
75        .with_table(plain_table)
76        .with_paragraph(heading(
77            "Merged cells: a spanning header row and a vertically merged column",
78            true,
79        ))
80        .with_table(merged_table)
81        .with_paragraph(heading(
82            "Column widths, border color, shading and indentation",
83            true,
84        ))
85        .with_table(styled_table);
86
87    document.save_to_file(&path)?;
88    println!("Wrote {}", path.display());
89    Ok(())
90}
Source

pub fn with_alignment(self, alignment: Alignment) -> Table

Sets this table’s own horizontal alignment/positioning and returns it for chaining. See alignment’s doc comment.

Source

pub fn with_indent_twips(self, indent_twips: u32) -> Table

Sets this table’s indentation, in twips, and returns it for chaining. See indent_twips’s doc comment.

Examples found in repository?
examples/docx_tables.rs (line 57)
13fn main() -> office_toolkit::Result<()> {
14    let path = output_path("docx_tables.docx");
15
16    let plain_table = Table::new()
17        .with_row(
18            TableRow::new()
19                .with_cell(TableCell::with_text("Name"))
20                .with_cell(TableCell::with_text("Score")),
21        )
22        .with_row(
23            TableRow::new()
24                .with_cell(TableCell::with_text("Alice"))
25                .with_cell(TableCell::with_text("92")),
26        )
27        .with_row(
28            TableRow::new()
29                .with_cell(TableCell::with_text("Bob"))
30                .with_cell(TableCell::with_text("87")),
31        );
32
33    let merged_table = Table::new()
34        .with_row(
35            TableRow::new()
36                .with_repeat_as_header_row(true)
37                .with_cell(TableCell::with_text("Quarterly report").with_horizontal_span(3)),
38        )
39        .with_row(
40            TableRow::new()
41                .with_cell(
42                    TableCell::with_text("Region").with_vertical_merge(VerticalMerge::Restart),
43                )
44                .with_cell(TableCell::with_text("Q1"))
45                .with_cell(TableCell::with_text("Q2")),
46        )
47        .with_row(
48            TableRow::new()
49                .with_cell(TableCell::new().with_vertical_merge(VerticalMerge::Continue))
50                .with_cell(TableCell::with_text("1,200"))
51                .with_cell(TableCell::with_text("1,350")),
52        );
53
54    let styled_table = Table::new()
55        .with_column_widths(vec![3_000, 3_000, 3_000])
56        .with_border_color("2E74B5")
57        .with_indent_twips(360)
58        .with_row(
59            TableRow::new()
60                .with_height_twips(500)
61                .with_cell(TableCell::with_text("Header A").with_shading_color("D9E2F3"))
62                .with_cell(TableCell::with_text("Header B").with_shading_color("D9E2F3"))
63                .with_cell(TableCell::with_text("Header C").with_shading_color("D9E2F3")),
64        )
65        .with_row(
66            TableRow::new()
67                .with_cant_split(true)
68                .with_cell(TableCell::with_text("1").with_border(true))
69                .with_cell(TableCell::with_text("2").with_border(true))
70                .with_cell(TableCell::with_text("3").with_border(true)),
71        );
72
73    let document = Document::new()
74        .with_paragraph(heading("A plain table", false))
75        .with_table(plain_table)
76        .with_paragraph(heading(
77            "Merged cells: a spanning header row and a vertically merged column",
78            true,
79        ))
80        .with_table(merged_table)
81        .with_paragraph(heading(
82            "Column widths, border color, shading and indentation",
83            true,
84        ))
85        .with_table(styled_table);
86
87    document.save_to_file(&path)?;
88    println!("Wrote {}", path.display());
89    Ok(())
90}
Source

pub fn with_style_id(self, style_id: impl Into<String>) -> Table

Sets the id of a named table style to apply and returns it for chaining. See style_id’s doc comment.

Trait Implementations§

Source§

impl Clone for Table

Source§

fn clone(&self) -> Table

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Table

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for Table

Source§

fn default() -> Table

Returns the “default value” for a type. Read more
Source§

impl PartialEq for Table

Source§

fn eq(&self, other: &Table) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Table

Auto Trait Implementations§

§

impl Freeze for Table

§

impl RefUnwindSafe for Table

§

impl Send for Table

§

impl Sync for Table

§

impl Unpin for Table

§

impl UnsafeUnpin for Table

§

impl UnwindSafe for Table

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.