介绍

Aspose.Cells FOSS for Rust 通过 aspose-cells-foss-rust crate 暴露其功能,核心围绕一组紧凑的核心类型:Workbook、Worksheet、Cells、Cell 和 DocumentProperties,每个类型都有相匹配的 *Mut 访问器用于写入。本文系统性地巡览该核心 API 表面——不仅仅是单一特性,而是每个基于该 crate 构建的应用都会使用的基础:创建和命名工作表、读取和写入带类型的单元格值、设置文档元数据、保护和隐藏工作表、调整行列大小、合并单元格以及防御性地加载文件。

该 crate 使用 MIT 许可证,面向 Rust 2021 版。几乎所有可能失败的操作都会返回 Result<_, CellsError>,因此在下面的示例中使用 ? 运算符进行错误处理的方式与在实际代码中完全相同。该 crate 引入了一小套运行时依赖,而不是从头实现所有功能——chrono 用于日期时间值,zip 用于 XLSX 包格式,roxmltree 用于 XML 解析,serde_json 用于结构化数据,sha2 和 base64 用于哈希和编码,getrandom 用于随机数。

下面的每个章节覆盖 API 的一个方面,列出相关的具体类型和方法,并附有从该 crate 示例代码中提取的可运行 Rust 示例。


关键特性

工作簿和工作表基础

一个 Workbook 初始为空,使用 Workbook::new(),包含一个名为 "Sheet1" 的工作表。额外的工作表通过 WorksheetsMut::add(name) 创建,该方法返回新工作表的索引。Worksheets/WorksheetsMut 也通过 active_sheet_name() 和 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());

已键入的单元格值和公式

Cells/CellsMut 通过 A1 样式引用(get("B3"))或行/列索引(get_by_index(row, column))来定位单元格。每个 Cell/CellMut 通过专用的 setter 接受已键入的值,因此无需字符串类型的转换,且公式会连同缓存值一起写入,这样文件在任何重新计算之前打开时就能得到正确的结果。

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());

文档属性

Workbook::get_document_properties_mut() 获取一个 DocumentProperties 对象,涵盖常见的元数据字段(标题、主题、作者、关键字、类别、公司),以及用于 OOXML 核心/扩展属性集的嵌套 CoreDocumentProperties(get_core_mut())和 ExtendedDocumentProperties(get_extended_mut())。

{
    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());

工作表保护与可见性

可以使用 set_visibility_type(VisibilityType::Hidden) 隐藏 Worksheet,使用 set_tab_color 着色,并通过 protect() 加上一个 WorksheetProtection 对象(通过 get_protection_mut())进行锁定,该对象精确控制在启用保护后哪些操作——如格式化单元格、选择锁定单元格等——仍然可用。

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());

行、列和合并单元格

CellsMut 将 get_rows()/get_columns() 公开为 RowsMut/ColumnsMut,用于调整大小和隐藏单独的行和列,并提供 merge(first_row, first_column, total_rows, total_columns) 将一系列单元格合并为一个合并区域。

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());

带诊断的防御性加载

实际的 XLSX 文件并不总是格式良好。LoadOptions 暴露修复标志(try_repair_package,try_repair_xml),并且 Workbook::get_load_diagnostics() 返回一个 LoadDiagnostics 对象,其 issues() 报告加载器发现并修复的内容。

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());

快速入门

# Cargo.toml
[dependencies]
aspose-cells-foss-rust = { git = "https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Rust" }

一个涉及工作簿、工作表、单元格和文档属性基础的最小会话:

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(())
}

支持的格式

格式扩展名读取写入
XLSX.xlsx✓✓

XLSX 是本次发布的重点:通过 Workbook::load_xlsx 和 Workbook::save 实现完整的往返读取和写入,LoadFormat 与 SaveFormat 枚举用于控制显式的格式选择。


开源与许可

Aspose.Cells FOSS for Rust 是 MIT 许可证。完整的源代码可在 GitHub 上获取,许可证允许商业使用、修改和再分发。


快速入门

相关资源