Introduction
Aspose.Cells FOSS for Rust exposes its functionality through the aspose-cells-foss-rust
crate, centered on a compact set of core types: Workbook, Worksheet, Cells, Cell, and
DocumentProperties, each with matching *Mut accessors for write access. This post is a
systematic tour of that core API surface — not one narrow feature, but the fundamentals every
application built on the crate ends up using: creating and naming worksheets, reading and
writing typed cell values, setting document metadata, protecting and hiding worksheets, sizing
rows and columns, merging cells, and loading files defensively.
The crate is MIT licensed and targets Rust edition 2021. Nearly every fallible operation returns
Result<_, CellsError>, so error handling with the ? operator runs through the examples below
the same way it runs through real code. The crate does pull in a small set of runtime
dependencies rather than reimplementing everything from scratch — chrono for date-time values,
zip for the XLSX package format, roxmltree for XML parsing, serde_json for structured data,
sha2 and base64 for hashing and encoding, and getrandom for randomness.
Each section below covers one area of the API with the concrete types and methods involved, backed by working Rust examples drawn from the crate’s own sample code.
Key Features
Workbook and Worksheet Fundamentals
A Workbook starts empty with Workbook::new(), carrying one worksheet named "Sheet1".
Additional sheets come from WorksheetsMut::add(name), which returns the new sheet’s index.
Worksheets/WorksheetsMut also track which sheet is active via active_sheet_name() and
set_active_sheet_name().
let mut workbook = Workbook::new();
{
let mut worksheets = workbook.get_worksheets_mut();
let sheet = worksheets.get(0)?;
sheet.set_name("Summary")?;
let detail_index = worksheets.add("Detail")?;
let detail = worksheets.get(detail_index)?;
detail.get_cells_mut().get("A1")?.put_value_string("Detail data")?;
worksheets.set_active_sheet_name("Detail")?;
}
let sheets = workbook.get_worksheets();
println!("Worksheet count: {}", sheets.count());
println!("Active sheet: {}", sheets.active_sheet_name());
Typed Cell Values and Formulas
Cells/CellsMut address a cell by A1-style reference (get("B3")) or by row/column index
(get_by_index(row, column)). Each Cell/CellMut accepts typed values through dedicated
setters, so no stringly-typed conversions are required, and formulas are written together with a
cached value so the file opens with correct results before any recalculation.
let mut workbook = Workbook::new();
{
let mut worksheets = workbook.get_worksheets_mut();
let sheet = worksheets.get(0)?;
let mut cells = sheet.get_cells_mut();
cells.get("A1")?.put_value_string("Hello")?;
cells.get("B1")?.put_value_i32(123)?;
cells.get("C1")?.put_value_bool(true)?;
cells.get("D1")?.put_value_decimal(12.5)?;
cells.get("F1")?.put_value_i32(10)?;
cells.get("G1")?
.put_formula_with_cached_value("=F1*2", CellValue::Number(20.0))?;
}
workbook.save("typed-values.xlsx")?;
let loaded = Workbook::load_xlsx("typed-values.xlsx")?;
let sheet = loaded.worksheet("Sheet1")?;
let cells = sheet.get_cells();
println!(
"{:?}: {}",
cells.get("B1")?.value_type(),
cells.get("B1")?.display_string_value()
);
println!("G1 cached value -> {}", cells.get("G1")?.display_string_value());
Document Properties
Workbook::get_document_properties_mut() reaches a DocumentProperties object covering the
common metadata fields (title, subject, author, keywords, category, company), plus a nested
CoreDocumentProperties (get_core_mut()) and ExtendedDocumentProperties
(get_extended_mut()) for OOXML core/extended property sets.
{
let properties = workbook.get_document_properties_mut();
properties.set_title("Annual Sales Report 2024");
properties.set_subject("Financial Performance Analysis");
properties.set_author("Finance Department");
properties.set_keywords("sales, finance, 2024, report");
properties.set_category("Financial Reports");
properties.set_company("Acme Corporation");
let core = properties.get_core_mut();
core.set_creator("Finance Department");
core.set_created(Some(Utc::now()));
let extended = properties.get_extended_mut();
extended.set_company("Acme Corporation");
}
workbook.save("with-properties.xlsx")?;
let loaded = Workbook::load_xlsx("with-properties.xlsx")?;
let properties = loaded.get_document_properties();
println!("Title: {}", properties.get_title());
println!("Core creator: {}", properties.get_core().get_creator());
Worksheet Protection and Visibility
A Worksheet can be hidden with set_visibility_type(VisibilityType::Hidden), tinted with
set_tab_color, and locked down with protect() plus a WorksheetProtection object (via
get_protection_mut()) that controls exactly which actions — formatting cells, selecting locked
cells, and so on — stay available once protection is on.
let mut workbook = Workbook::new();
{
let mut worksheets = workbook.get_worksheets_mut();
let layout = worksheets.get(0)?;
layout.set_name("Layout")?;
layout.set_visibility_type(VisibilityType::Hidden);
layout.set_tab_color(Color::from_argb(255, 34, 68, 102));
layout.set_show_gridlines(false);
layout.set_right_to_left(true);
layout.set_zoom(85)?;
layout.protect();
let protection = layout.get_protection_mut();
protection.set_objects(true);
protection.set_format_cells(true);
protection.set_select_locked_cells(true);
}
workbook.save("protected.xlsx")?;
let loaded = Workbook::load_xlsx("protected.xlsx")?;
let sheet = loaded.worksheet("Layout")?;
println!("Visibility: {:?}", sheet.get_visibility_type());
println!("Protected: {}", sheet.is_protected());
Rows, Columns, and Merged Cells
CellsMut exposes get_rows()/get_columns() as RowsMut/ColumnsMut for sizing and hiding
individual rows and columns, and merge(first_row, first_column, total_rows, total_columns) to
combine a range of cells into one merged region.
let mut workbook = Workbook::new();
{
let mut worksheets = workbook.get_worksheets_mut();
let sheet = worksheets.get(0)?;
let mut cells = sheet.get_cells_mut();
cells.get("A1")?.put_value_string("Merged")?;
cells.get("C4")?.put_value_i32(99)?;
cells.get_rows().get(1).set_height(22.5)?;
cells.get_rows().get(3).set_is_hidden(true)?;
cells.get_columns().get(0).set_width(18.25)?;
cells.get_columns().get(2).set_is_hidden(true)?;
let mut cells = sheet.get_cells_mut();
cells.merge(0, 0, 2, 2)?;
}
workbook.save("rows-columns.xlsx")?;
let loaded = Workbook::load_xlsx("rows-columns.xlsx")?;
let sheet = loaded.worksheet("Sheet1")?;
println!(
"Row 2 height: {}",
sheet.get_rows().get(1).get_height().unwrap_or_default()
);
println!(
"Column A width: {}",
sheet.get_columns().get(0).get_width().unwrap_or_default()
);
println!("Merged regions: {}", sheet.get_cells().get_merged_cells().len());
Defensive Loading with Diagnostics
Real-world XLSX files are not always well-formed. LoadOptions exposes repair flags
(try_repair_package, try_repair_xml), and Workbook::get_load_diagnostics() returns a
LoadDiagnostics object whose issues() reports what the loader found and repaired.
let options = LoadOptions {
try_repair_package: true,
try_repair_xml: true,
..LoadOptions::default()
};
let loaded = Workbook::load_xlsx_with_options(&path, &options)?;
let sheet = loaded.worksheet("Sheet1")?;
let cells = sheet.get_cells();
println!(
"Loaded workbook with {} worksheet(s) and {} diagnostic issue(s).",
loaded.get_worksheets().count(),
loaded.get_load_diagnostics().issues().len()
);
println!("First item: {}", cells.get("A2")?.display_string_value());
Quick Start
# Cargo.toml
[dependencies]
aspose-cells-foss-rust = { git = "https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Rust" }A minimal session touching workbook, worksheet, cell, and document-property basics:
use aspose_cells_foss_rust::{CellValue, Workbook};
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let mut workbook = Workbook::new();
{
let mut worksheets = workbook.get_worksheets_mut();
let sheet = worksheets.get(0)?;
sheet.set_name("Report")?;
let mut cells = sheet.get_cells_mut();
cells.get("A1")?.put_value_string("Item")?;
cells.get("B1")?.put_value_string("Quantity")?;
cells.get("A2")?.put_value_string("Widgets")?;
cells.get("B2")?.put_value_i32(12)?;
cells.get("B3")?
.put_formula_with_cached_value("=SUM(B2:B2)", CellValue::Number(12.0))?;
}
workbook.get_document_properties_mut().set_title("Quick Start Report");
workbook.save("report.xlsx")?;
let loaded = Workbook::load_xlsx("report.xlsx")?;
let sheet = loaded.worksheet("Report")?;
let cells = sheet.get_cells();
println!("Title: {}", loaded.get_document_properties().get_title());
println!("Total formula -> {}", cells.get("B3")?.display_string_value());
Ok(())
}
Supported Formats
| Format | Extension | Read | Write |
|---|---|---|---|
| XLSX | .xlsx | ✓ | ✓ |
XLSX is the focus of the current release: full round-trip read and write via
Workbook::load_xlsx and Workbook::save, with LoadFormat and SaveFormat enums governing
explicit format selection.
Open Source & Licensing
Aspose.Cells FOSS for Rust is MIT licensed. The complete source code is available on GitHub, and the license permits commercial use, modification, and redistribution.