Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Architecture

ABCrimson edited this page Mar 2, 2026 · 6 revisions

Architecture

modern-xlsx is a hybrid Rust WASM + TypeScript library for reading and writing XLSX files.

Layer Diagram

 ┌──────────────────────────────────────────┐
 │ TypeScript API │
 │ Workbook · Worksheet · Cell │
 │ StyleBuilder · RichTextBuilder │
 │ Utilities (dates, cell refs, CSV, JSON) │
 └────────────────┬─────────────────────────┘
 │ JSON string
 ┌────────────────┴─────────────────────────┐
 │ WASM Bridge (wasm-bindgen) │
 │ read() · write() · readJson() │
 └────────────────┬─────────────────────────┘
 │
 ┌────────────────┴─────────────────────────┐
 │ Rust Core (modern-xlsx-core) │
 │ ZIP (deflate) · XML (quick-xml SAX) │
 │ SharedStringTable · Style resolution │
 │ Content types · Relationships │
 └──────────────────────────────────────────┘

Data Flow

Reader Path

Uint8Array → WASM read()
 → ZIP decompress (zip crate)
 → Parse XML parts (quick-xml SAX)
 → Build WorkbookData struct
 → Serialize to JSON (serde_json)
 → JSON.parse() in JS
 → Workbook class wraps raw data

Writer Path

Workbook.toBuffer()
 → Serialize to JSON (JSON.stringify)
 → WASM write()
 → Build SST from shared string cells
 → Generate XML parts (quick-xml Writer)
 → ZIP compress (zip crate, deflate)
 → Return Uint8Array

Why JSON Bridge?

Data crosses the WASM boundary as JSON strings, not via serde_wasm_bindgen. Benchmarks show this is 8–13x faster for large workbooks because:

  1. serde_json serialization in Rust is heavily optimized (itoa, ryu for numbers)
  2. JSON.parse() is one of the fastest built-in V8/SpiderMonkey operations
  3. A single WASM boundary crossing replaces thousands of individual wasm_bindgen calls

Rust Core Modules

Module Purpose
lib.rs WorkbookData, SheetData, CellData — shared types
reader.rs Read orchestrator (ZIP → parse → WorkbookData)
writer.rs Write orchestrator (WorkbookData → XML → ZIP)
streaming.rs Streaming reader/writer for large files
ooxml/ Individual OOXML part parsers
number_format.rs Excel number format code parser
errors.rs ModernXlsxError error type

OOXML Parsers

Parser OOXML Part
shared_strings.rs xl/sharedStrings.xml
styles.rs xl/styles.xml
worksheet.rs xl/worksheets/sheet*.xml
workbook.rs xl/workbook.xml
relationships.rs *.rels files
content_types.rs [Content_Types].xml
doc_props.rs docProps/core.xml, docProps/app.xml
comments.rs xl/comments*.xml
theme.rs xl/theme/theme1.xml
calc_chain.rs xl/calcChain.xml

Performance Patterns

  • SAX parsing — quick-xml streams events, never builds a DOM tree
  • Vec::with_capacity() — pre-allocated parse buffers on all XML parsers
  • push_entity() — zero-allocation XML entity resolution (writes into caller's buffer)
  • from_utf8().unwrap_or_default() — avoids lossy conversion + allocation
  • entries.remove() — moves data out of HashMap instead of cloning
  • drain() — moves preserved entries instead of cloning large blobs
  • Binary search insertion — rows inserted in sorted order
  • itoa::Buffer — zero-allocation integer formatting in XML

Bundle Size

Component Size
WASM binary ~870 KB
JS wrapper ~25 KB
Total ~895 KB

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /