Skip to main content

xlsx_rich_data/
xlsx_rich_data.rs

1//! Excel rich cell data: dates, booleans, formulas (plain, array, and
2//! shared), multi-run rich text, hyperlinks, and comments. One tab per
3//! feature.
4//!
5//! Run with: `cargo run -p office-toolkit --example xlsx_rich_data`
6
7use std::path::{Path, PathBuf};
8
9use office_toolkit::SaveToFile;
10use office_toolkit::excel::{Cell, CellComment, CellHyperlink, ExcelDateTime, RichTextRun, Sheet};
11use office_toolkit::prelude::*;
12
13fn main() -> office_toolkit::Result<()> {
14    let path = output_path("xlsx_rich_data.xlsx");
15
16    let dates_and_booleans_sheet = Sheet::new("Dates and booleans")
17        .with_row(Row::new().with_cell(Cell::date(ExcelDateTime::date(2026, 7, 21))))
18        .with_row(Row::new().with_cell(Cell::date(
19            ExcelDateTime::date(2026, 7, 21).with_time(14, 30, 0),
20        )))
21        .with_row(
22            Row::new()
23                .with_cell(Cell::boolean(true))
24                .with_cell(Cell::boolean(false)),
25        );
26
27    // An array/shared formula's `ref` must be a range whose top-left cell
28    // is the cell the `<f t="array"|"shared">` element actually sits in —
29    // `with_cell` fills a row left-to-right starting at column A, so each
30    // formula cell below is positioned to land exactly on its own `ref`'s
31    // first cell, with plain cached-value cells (no `<f>`) filling out the
32    // rest of the declared range, matching how Excel itself writes a
33    // multi-cell array/shared formula. The previous version declared
34    // ranges like "D1:D3"/"E1:E3" while the formula cells actually landed
35    // in column A — a real cell/range mismatch Excel refuses to open
36    // without repairing.
37    let formulas_sheet = Sheet::new("Formulas")
38        .with_row(
39            Row::new()
40                .with_cell(Cell::number(10.0))
41                .with_cell(Cell::number(20.0))
42                .with_cell(Cell::formula("A1+B1").with_cached_value(30.0)),
43        )
44        .with_row(
45            Row::new()
46                .with_cell(Cell::array_formula("A1:A3*2", "A2:C2").with_cached_value(20.0))
47                .with_cell(Cell::number(40.0))
48                .with_cell(Cell::number(60.0)),
49        )
50        .with_row(
51            Row::new()
52                .with_cell(Cell::shared_formula("A1+1", 0, "A3:C3").with_cached_value(11.0))
53                .with_cell(Cell::shared_formula_follower(0).with_cached_value(21.0))
54                .with_cell(Cell::shared_formula_follower(0).with_cached_value(31.0)),
55        );
56
57    let rich_text_sheet =
58        Sheet::new("Rich text").with_row(Row::new().with_cell(Cell::rich_text(vec![
59        RichTextRun::new("Bold red, ").with_bold(true).with_font_color("FFC00000"),
60        RichTextRun::new("then italic blue.").with_italic(true).with_font_color("FF2E74B5"),
61    ])));
62
63    let hyperlinks_sheet = Sheet::new("Hyperlinks")
64        .with_row(
65            Row::new()
66                .with_text("Visit Rust")
67                .with_text("Jump to C1")
68                .with_text("You've arrived"),
69        )
70        .with_hyperlink(
71            CellHyperlink::external("A1", "https://www.rust-lang.org")
72                .with_tooltip("Opens in your browser"),
73        )
74        .with_hyperlink(CellHyperlink::internal("B1", "'Hyperlinks'!C1"));
75
76    let comments_sheet = Sheet::new("Comments")
77        .with_row(
78            Row::new()
79                .with_text("Hover B1 for a comment")
80                .with_text("Reviewed"),
81        )
82        .with_comment(CellComment::new(
83            "A1",
84            "Reviewer",
85            "Double-check this figure before publishing.",
86        ))
87        .with_comment(
88            CellComment::new("B1", "Reviewer", "Looks correct.")
89                .with_rich_text(vec![RichTextRun::new("Looks correct.").with_bold(true)]),
90        );
91
92    let workbook = Workbook::new()
93        .with_sheet(dates_and_booleans_sheet)
94        .with_sheet(formulas_sheet)
95        .with_sheet(rich_text_sheet)
96        .with_sheet(hyperlinks_sheet)
97        .with_sheet(comments_sheet);
98
99    workbook.save_to_file(&path)?;
100    println!("Wrote {}", path.display());
101    Ok(())
102}
103
104/// Every example in this directory writes its output under
105/// `tests-data/output/`, resolved relative to this crate's own manifest so
106/// it works no matter what directory `cargo run` was invoked from.
107fn output_path(filename: &str) -> PathBuf {
108    Path::new(env!("CARGO_MANIFEST_DIR"))
109        .join("../../tests-data/output")
110        .join(filename)
111}