excelize-rs 0.1.0

Rust language library for reading and writing Microsoft Excel (XLAM / XLSM / XLSX / XLTM / XLTX) spreadsheets
Documentation
excelize-rs-0.1.0 has been yanked.

Excelize for Rust

A Rust port of the Go 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:

[dependencies]
excelize-rs = "0.1"

Create spreadsheet

Here is a minimal example that creates a spreadsheet file:

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:

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:

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

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

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:

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:

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

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 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, following the original Go excelize project.