excelize-rs 0.1.9

Rust language library for reading and writing Microsoft Excel (XLAM / XLSM / XLSX / XLTM / XLTX) spreadsheets
Documentation
# Excelize for Rust

A Rust port of the Go [excelize](https://github.com/xuri/excelize) library, providing a set of functions that allow you to write to and read from XLAM / XLSM / XLSX / XLTM / XLTX files. Supports reading and writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. Based on ECMA-376 and ISO/IEC 29500 international standards.

## Features

- Create, read and update XLSX / XLSM / XLTX / XLTM / XLAM documents
- Cell values (string, number, boolean, date, rich text), formulas, hyperlinks and comments
- A formula calculation engine with 450+ Excel functions (math, statistical, financial, engineering, text, date, lookup, database, ...)
- Cell styles: fonts, fills, borders, alignment, number formats and conditional formatting
- Charts, pictures, shapes, sparklines, slicers, tables and pivot tables
- Streaming writer for generating worksheets with huge amounts of data
- Document encryption and decryption (Standard and Agile encryption)
- Merged cells, data validation, defined names, document properties and more

## Basic Usage

### Installation

Add the dependency to your `Cargo.toml`:

```toml
[dependencies]
excelize-rs = "0.1"
```

### Create spreadsheet

Here is a minimal example that creates a spreadsheet file:

```rust
use excelize_rs::errors::Result;
use excelize_rs::{File, Options};

fn main() -> Result<()> {
    let mut f = File::new_with_options(Options::default());

    // Create a new worksheet
    let index = f.new_sheet("Sheet2")?;

    // Set value of cells
    f.set_cell_str("Sheet2", "A2", "Hello world.")?;
    f.set_cell_int("Sheet1", "B2", 100)?;

    // Set the active worksheet of the workbook
    f.set_active_sheet(index)?;

    // Save the spreadsheet
    f.save_as("Book1.xlsx")?;
    f.close()?;
    Ok(())
}
```

### Reading spreadsheet

Read values from an existing spreadsheet document:

```rust
use excelize_rs::errors::Result;
use excelize_rs::{File, Options};

fn main() -> Result<()> {
    let f = File::open_file("Book1.xlsx", Options::default())?;

    // Get value from a cell
    let cell = f.get_cell_value("Sheet1", "B2")?;
    println!("B2: {cell}");

    // Get all rows in Sheet1
    let rows = f.get_rows("Sheet1", Options::default())?;
    for row in rows {
        for cell in row {
            print!("{cell}\t");
        }
        println!();
    }

    // Evaluate a formula cell
    let result = f.calc_cell_value("Sheet1", "C1")?;
    println!("C1 = {result}");
    Ok(())
}
```

### Cell styles

Create a style and apply it to a range of cells:

```rust
use excelize_rs::errors::Result;
use excelize_rs::styles::{Alignment, Fill, Font, Style};
use excelize_rs::{File, Options};

fn main() -> Result<()> {
    let mut f = File::new_with_options(Options::default());

    let style = Style {
        font: Some(Font {
            name: Some("Arial".to_string()),
            size: Some(12.0),
            bold: Some(true),
            color: Some("FF0000".to_string()),
            ..Default::default()
        }),
        fill: Fill {
            r#type: "pattern".to_string(),
            pattern: 1,
            color: vec!["FFFF00".to_string()],
            ..Default::default()
        },
        alignment: Some(Alignment {
            horizontal: "center".to_string(),
            vertical: "middle".to_string(),
            ..Default::default()
        }),
        ..Default::default()
    };
    let style_id = f.new_style(&style)?;

    f.set_cell_str("Sheet1", "A1", "Styled cell")?;
    f.set_cell_style("Sheet1", "A1", "A1", style_id)?;

    f.save_as("Book1.xlsx")?;
    f.close()?;
    Ok(())
}
```

### Add chart to spreadsheet file

```rust
use excelize_rs::chart::{Chart, ChartSeries, ChartTitle, ChartType};
use excelize_rs::errors::Result;
use excelize_rs::xml::common::RichTextRun;
use excelize_rs::{File, Options};

fn main() -> Result<()> {
    let mut f = File::new_with_options(Options::default());

    f.set_cell_str("Sheet1", "A1", "Fruit")?;
    f.set_cell_str("Sheet1", "B1", "Apple")?;
    f.set_cell_str("Sheet1", "C1", "Orange")?;
    f.set_cell_str("Sheet1", "A2", "Small")?;
    f.set_cell_int("Sheet1", "B2", 2)?;
    f.set_cell_int("Sheet1", "C2", 3)?;

    let chart = Chart {
        r#type: ChartType::COL,
        series: vec![ChartSeries {
            name: "Sheet1!$A$2".to_string(),
            categories: "Sheet1!$B$1:$C$1".to_string(),
            values: "Sheet1!$B$2:$C$2".to_string(),
            ..Default::default()
        }],
        title: ChartTitle {
            paragraph: vec![RichTextRun {
                text: "Fruit Chart".to_string(),
                ..Default::default()
            }],
            ..Default::default()
        },
        ..Default::default()
    };
    f.add_chart("Sheet1", "E1", &chart)?;

    f.save_as("Book1.xlsx")?;
    f.close()?;
    Ok(())
}
```

### Add picture to spreadsheet file

```rust
use excelize_rs::errors::Result;
use excelize_rs::{File, Options};

fn main() -> Result<()> {
    let mut f = File::open_file("Book1.xlsx", Options::default())?;

    // Insert a picture anchored at cell A2
    f.add_picture("Sheet1", "A2", "image.png", None)?;

    f.save()?;
    f.close()?;
    Ok(())
}
```

### Streaming write

Generate worksheets with huge amounts of data using the streaming writer. Note that the writer borrows the workbook, so it must be dropped (for example by scoping it) before saving:

```rust
use excelize_rs::errors::Result;
use excelize_rs::{File, Options};

fn main() -> Result<()> {
    let mut f = File::new_with_options(Options::default());

    {
        let mut sw = f.new_stream_writer("Sheet1")?;
        for row in 1..=100_000i64 {
            sw.set_row(&format!("A{row}"), &[&row, &"value"], None)?;
        }
        sw.flush()?;
    }

    f.save_as("Book1.xlsx")?;
    f.close()?;
    Ok(())
}
```

### Encrypted workbook

Open and save password-protected workbooks with the `password` option:

```rust
use excelize_rs::errors::Result;
use excelize_rs::{File, Options};

fn main() -> Result<()> {
    // Open an encrypted workbook
    let mut f = File::open_file(
        "Book1.xlsx",
        Options {
            password: "password".to_string(),
            ..Default::default()
        },
    )?;

    // Save with encryption
    f.save_as_with_options(
        "Book1-encrypted.xlsx",
        Options {
            password: "password".to_string(),
            ..Default::default()
        },
    )?;
    f.close()?;
    Ok(())
}
```

## Running tests

```bash
cargo test
```

The test suite covers unit tests, formula-calculation cases ported from the Go version, and end-to-end round-trip integration tests.

## Relationship to the Go version

This project is a Rust port of the Go [excelize](https://github.com/xuri/excelize) library. The code in `src/` is organized to mirror the Go package layout file by file, and the public API follows Go naming conventions converted to `snake_case`.

## Contributing

Contributions are welcome. Please open an issue or pull request.

## Licenses

This project is licensed under the [BSD 3-Clause License](LICENSE), following the original Go excelize project.