3 releases
Uses new Rust 2024
| 0.1.1-alpha.2 | Mar 19, 2026 |
|---|---|
| 0.1.1-alpha.1 | Mar 3, 2026 |
| 0.1.0 | Mar 2, 2026 |
#2486 in Parser implementations
Used in ooxml-wml
110KB
2.5K
SLoC
ooxml
Rust library for reading and writing Office Open XML formats: DOCX, XLSX, and PPTX.
Crates
| Crate | Description | Docs |
|---|---|---|
ooxml-wml |
WordprocessingML — read/write .docx |
|
ooxml-sml |
SpreadsheetML — read/write .xlsx |
|
ooxml-pml |
PresentationML — read/write .pptx |
|
ooxml-dml |
DrawingML — shared graphics layer | |
ooxml-omml |
Office Math Markup Language | |
ooxml-opc |
OPC packaging core (ZIP, relationships, content types) |
Quick Start
Read a Word document
use ooxml_wml::Document;
use ooxml_wml::ext::{BodyExt, ParagraphExt};
let doc = Document::open("document.docx")?;
// All paragraphs
for para in doc.body().paragraphs() {
println!("{}", para.text());
}
// Full plain text
println!("{}", doc.text());
Write a Word document
use ooxml_wml::{DocumentBuilder, ListType};
let mut builder = DocumentBuilder::new();
// Heading
{
let para = builder.body_mut().add_paragraph();
let run = para.add_run();
run.set_text("My Document");
run.set_bold(true);
run.set_font_size(48); // half-points, so 24pt
}
// Paragraph
builder.add_paragraph("A regular paragraph.");
// Bulleted list
let list_id = builder.add_list(ListType::Bullet);
for item in ["First", "Second", "Third"] {
let para = builder.body_mut().add_paragraph();
para.add_run().set_text(item);
para.set_numbering(list_id, 0);
}
// Table
let table = builder.body_mut().add_table();
let row = table.add_row();
for header in ["Name", "Value"] {
let cell = row.add_cell();
cell.add_paragraph().add_run().set_text(header);
}
builder.save("output.docx")?;
Read a spreadsheet
use ooxml_sml::{Workbook, WorksheetExt, RowExt, CellResolveExt};
let mut workbook = Workbook::open("data.xlsx")?;
println!("Sheets: {:?}", workbook.sheet_names());
let sheet = workbook.resolved_sheet(0)?;
for row in sheet.rows() {
for cell in row.cells_iter() {
print!("{}\t", cell.value_as_string(sheet.context()));
}
println!();
}
Read a presentation
use ooxml_pml::{Presentation, ShapeExt};
let mut pres = Presentation::open("slides.pptx")?;
for slide in pres.slides()? {
println!("--- Slide {} ---", slide.index() + 1);
for shape in slide.shapes() {
if let Some(text) = shape.text() {
println!("{}", text);
}
}
if let Some(notes) = slide.notes() {
println!("Notes: {}", notes);
}
}
Features
Each crate uses fine-grained feature flags for smaller compile times. The full feature (enabled by default) includes everything.
ooxml-wml features: wml-styling, wml-tables, wml-layout, wml-hyperlinks, wml-drawings, wml-numbering, wml-comments, wml-fields, wml-track-changes, wml-settings, wml-math, wml-charts
ooxml-sml features: sml-styling, sml-formulas, sml-layout, sml-filtering, sml-validation, sml-comments, sml-charts, sml-hyperlinks, sml-pivot, sml-tables, and more
ooxml-pml features: pml-transitions, pml-animations, pml-notes, pml-comments, pml-styling, pml-masters, pml-hyperlinks, pml-charts
Example minimal dependency:
[dependencies]
ooxml-wml = { version = "0.1", default-features = false, features = ["wml-styling"] }
Design
- Typed — every XML element maps to a Rust struct, generated from the ECMA-376 RELAX NG schemas
- Roundtrip-faithful — unknown elements and attributes are preserved, never silently dropped
- Lazy — large parts (worksheets, slide lists) are streamed rather than parsed upfront
- Spec-driven — types and names follow ECMA-376 / ISO 29500; deviations are documented
Status
The library is in active development at v0.1. The core reading and writing APIs for all three formats are functional. See TODO.md for the backlog and SPEC.md for the full roadmap.
License
Licensed under either of MIT or Apache-2.0 at your option.
Dependencies
~1.6–2.3MB
~41K SLoC