BetterOffice

Rust

The crates.io packages — three format facades and the per-layer crates behind them

The crates are the engines the WebAssembly packages are compiled from, without the wasm boundary: parsed models and Yrs state are plain Rust structs, and calls do not cross JSON. Use one of the three facades unless you want a single stage of the pipeline.

cargo add betteroffice-xlsx

Open, edit, render, save

use betteroffice_xlsx::{CalculationOptions, CellRef, RenderOptions, SheetId, Workbook};

let mut workbook = Workbook::open_recalculated(&xlsx_bytes, CalculationOptions::default())?;

workbook.edit_cell(
    SheetId(0),
    CellRef::parse_a1("A1").unwrap(),
    "42",
    CalculationOptions::default(),
)?;

let png = workbook.render_sheet(SheetId(0), &RenderOptions::default())?;
let saved = workbook.save()?;

Saving preserves the source package: parts the model does not represent — charts, pivot tables, comments, macros, custom XML and their relationships — are kept, and sheets an edit did not touch are copied through byte for byte. A sheet you do edit is reserialized from the model, so unmodeled markup on that one sheet is lost.

DOCX and PPTX have the same shape:

use betteroffice_docx::Document;

let mut document = Document::open(&docx_bytes)?;
let paragraph_id = document.paragraphs()[0].para_id.clone().unwrap();

document.replace_paragraph_text(&paragraph_id, "Updated in Rust")?;
let saved = document.save()?;
use betteroffice_pptx::Presentation;

let mut presentation = Presentation::open(&pptx_bytes)?;
let deck = presentation.snapshot()?; // slides, shapes, and text as plain structs

presentation.register_font("Inter", false, false, &font_bytes)?;
let rendered = presentation.render_slide(0)?; // display list + hit-test metadata
let saved = presentation.save()?;

open_with_limits on DOCX and PPTX swaps the parser's default resource budget for one you supply, which is what a host ingesting untrusted uploads wants. A file past any cap is refused, never truncated.

Rendering

XLSX rasterizes by default: render_sheet returns a PNG, and the raster backend embeds Carlito to measure and paint cell text. DOCX keeps its raster backend behind a feature, because the default build still targets wasm32-unknown-unknown:

cargo add betteroffice-docx --features raster

PPTX has no rasterizer. render_slide returns the display list the browser editor paints — vector geometry, images, shaped text, caret data — alongside hit-test metadata, and it fails until at least one font face has been registered. Yrs edits reach that display list but are not projected back into PresentationML, so save re-zips the parts it retained rather than your edits.

The facades

CrateWhat it is
betteroffice-docxTyped native API for opening, editing, laying out, and saving DOCX documents.
betteroffice-xlsxTyped native API for opening, editing, collaborating, calculating, rendering, and saving XLSX workbooks.
betteroffice-pptxTyped native API for opening, editing, collaborating on, and rendering PPTX presentations.

The layers

CrateWhat it is
betteroffice-opcThe OPC container reader and writer, with zip-bomb and path-traversal limits enforced by construction. Shared by all three formats.
betteroffice-ooxml-textShared text shaping, measurement, line breaking, and bidirectional text.
betteroffice-drawingmlThe DrawingML colors, themes, shape models, and preset geometry shared by all three formats.
betteroffice-docx-parseWordprocessingML parsing, typed relationship models, and the canonical document contract.
betteroffice-docx-layoutDOCX pagination, line flow, tables, floats, notes, and display lists.
betteroffice-docx-editThe pilcrow-stream Yrs editing schema for DOCX.
betteroffice-docx-rasterThe tiny-skia backend that paints a DOCX display list to PNG. Never part of the wasm build.
betteroffice-xlsx-modelThe workbook, worksheet, and cell model: address types, values, styles. IO-free.
betteroffice-xlsx-parseStreaming SpreadsheetML parse and serialize.
betteroffice-xlsx-calcThe standalone formula engine: lexer, parser, dependency graph, and evaluator, written spec-first from ECMA-376.
betteroffice-xlsx-opsThe invertible op log behind undo, redo, address remapping, and agent proposals.
betteroffice-xlsx-renderGrid geometry and the target-agnostic display list.
betteroffice-xlsx-rasterThe tiny-skia backend that paints an XLSX display list to PNG. Never part of the wasm build.
betteroffice-pptx-parseBounded PresentationML parsing and part-preserving package writes.
betteroffice-pptx-editThe Yrs deck model for PPTX.
betteroffice-pptx-renderSlide layout and the PPTX display-list compiler.

Every crate publishes to crates.io from one release train, so they always share a version.

On this page