Skip to main content

docx_tables/
docx_tables.rs

1//! Word tables: a plain grid, a table with merged cells (horizontal span
2//! and vertical merge), and a table with borders/shading/column widths.
3//! One page per feature.
4//!
5//! Run with: `cargo run -p office-toolkit --example docx_tables`
6
7use std::path::{Path, PathBuf};
8
9use office_toolkit::SaveToFile;
10use office_toolkit::prelude::*;
11use office_toolkit::word::{Run, Table, TableCell, TableRow, VerticalMerge};
12
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}
91
92fn heading(text: &str, new_page: bool) -> Paragraph {
93    Paragraph::new()
94        .with_run(Run::new(text).with_bold(true).with_font_size(28))
95        .with_page_break_before(new_page)
96}
97
98/// Every example in this directory writes its output under
99/// `tests-data/output/`, resolved relative to this crate's own manifest so
100/// it works no matter what directory `cargo run` was invoked from.
101fn output_path(filename: &str) -> PathBuf {
102    Path::new(env!("CARGO_MANIFEST_DIR"))
103        .join("../../tests-data/output")
104        .join(filename)
105}