This audit maps the Microsoft Office feature surface — Word, Excel, PowerPoint, Access — against what the zoffice engine actually implements today. Granularity is the feature group (styles, charts, track-changes, pivot tables…), not the individual menu command; a command-level list would run to thousands of rows and obscure the shape. Every zoffice status below is grounded in an engine symbol read directly from src/writer.rs, src/calc.rs, src/impress.rs and src/base.rs, cross-checked against the source-derived engineering report.
The single most important finding is a read / write asymmetry. zoffice is a comprehensive, high-fidelity reader of ODF and OOXML across all six apps, and a WYSIWYG viewer in the desktop shell. It is not yet a full authoring suite: writing splits into three tiers, and only the narrowest one is lossless. Read that asymmetry first, then the per-app tables.
Tier 1 — Read
FULL. All six apps parse real ODF/OOXML packages: text, formatting, tables, styles, charts, animations, formulas, database catalogs. This is where zoffice is strongest — close to LibreOffice-grade coverage on the read path.
Tier 2 — Lossless patch
NARROW. replace_lossless (find/replace) and set_cell_lossless (single cell) edit the original package XML in place, preserving all formatting — but only for those narrow operations.
Tier 3 — Full save
CLOSING. Full-save fidelity is being closed incrementally. save_xlsx preserves formulas, merged cells, named ranges and number-vs-text cell types, and save_ods now writes the ODF spreadsheet with the same fidelity as xlsx (values, number/text types, formulas, merged ranges, named ranges); save_docx / save_odt preserve every paragraph property (alignment, indent, spacing, shading, page-break, heading & list level), full run-level character formatting (bold, italic, underline, strike, font, size, color, caps, super/subscript, letter-spacing, hyperlinks), and tables with cell merges, shading and page geometry. Still dropped: Calc cell number-formats / styles, and images.
✓ implemented / full ◐ partial — read-only, compute-only, or narrow ○ absent
Summary by component
| Component | MS app | Read | Write / edit | Estimated parity |
|---|---|---|---|---|
| Calc | Excel | ✓ full — 300+ functions, formula eval | ◐ 1-cell lossless; full save (xlsx + ods) keeps formulas/merges/named-ranges/types | ~55% (read-weighted) |
| Writer | Word | ✓ full — all structures parsed | ◐ find/replace + table-cell lossless; full save keeps paragraph properties, run formatting and tables | ~35% |
| Impress | PowerPoint | ✓ full — slides, animations, media | ◐ text + positioned shapes save (pptx + odp) · add / delete / reorder slide | ~25% |
| Base | Access | ◐ .odb only, embedded HSQLDB | ○ no DDL/DML write | ~10% |
Parity figures are estimates weighted toward the read path; treat them as directional, not measured. The per-feature rows below are the ground truth.
Excel → Calc
reads .xlsx / .xls / .ods / .fods / .csv · engine: src/calc.rs
| Feature group | Excel | zoffice Calc | Evidence / note |
|---|---|---|---|
| Open formats | xlsx, xls, ods, csv | ✓ xlsx, xls, ods, fods, csv | full OOXML + ODF + legacy OLE2 read |
| Save formats | full-fidelity | ◐ xlsx and ods both keep formulas + merges + named ranges + numeric types; 1-cell lossless | save_xlsx writes <f>/<v>/mergeCells/definedNames; save_ods writes table:formula/spanned merges/table:named-expressions; number-formats + styles still dropped |
| Formula engine | ~480 functions | ✓ 300+ functions, recursive-descent eval | math, stats, financial, date, text, lookup, database, engineering, logical, info families |
| Dynamic arrays / spill | FILTER, SORT, UNIQUE, SEQUENCE | ✓ implemented | Excel-365 dynamic-array family present |
| Matrix functions | MMULT, MINVERSE, TRANSPOSE | ✓ implemented | MMULT / MINVERSE / MUNIT / MDETERM / TRANSPOSE |
| Number formatting | custom format codes | ✓ parsed + applied on display | number_formats, format-code engine |
| Named ranges | full | ✓ parsed + resolved | named_ranges_with_refs |
| Merged cells | full | ✓ read | enumerated |
| Comments / notes | full | ✓ read | calc.comments |
| Conditional formatting | full editor | ◐ read-only, not editable | conditional_formats enumerates rules |
| Data validation | full | ◐ read-only, not editable | data_validations |
| Charts | 50+ types, editable | ◐ read + render data, no edit | charts_render / charts_detail |
| PivotTables | full drag-drop builder | ◐ compute only, no builder | pivot_compute / pivot_compute_multi |
| Frozen panes | full | ◐ read flag only | has_frozen_panes |
| Sheet protection | full | ◐ read/enumerated | sheet_protections |
| Worksheet insert / delete | full | ○ absent | no add/remove sheet API |
| Sparklines | full | ◐ read, no editor | sparklines — x14:sparklineGroups → kind + data range + location cell |
| Slicers / timelines | full | ◐ read, no editor | slicers — xl/slicers + xl/timelines → kind, name, caption |
| Macros (VBA) | full | ◐ modules extracted, not executed | ole2::vba_modules reads vbaProject.bin; no Basic interpreter |
| Power Query / Power Pivot | full | ○ absent | — |
| Solver / Goal Seek | full | ◐ Goal Seek implemented; no Solver | goal_seek — single-input search against a target value |
| Root-cause attribution | — (no MS equivalent) | ✓ calc.rootcause | revision diff + dependency cone + counterfactual re-evaluation → ranked causes with contribution shares |
| Recalc critical path | — (Trace Precedents is one hop) | ✓ calc.critical_path | longest formula dependency chain over the workbook DAG |
| Dependency blast radius | — (Trace Dependents is one hop) | ✓ calc.impact_map | transitive dependent count per cell + the keystone cell + the sheets it spans |
| Pre-commit blast-radius gate | — | ✓ calc.cell_impact | what one pending cell edit would recalculate, with the cell's exact keystone rank, before it commits; a format whose formulas are not retained reports unknown, never safe |
| Export | ✓ PDF, HTML, Markdown, CSV | calc.pdf, to_html/to_markdown/to_csv |
Word → Writer
reads .odt / .docx / .doc / .rtf / .fodt · engine: src/writer.rs
| Feature group | Word | zoffice Writer | Evidence / note |
|---|---|---|---|
| Open formats | docx, doc, rtf, odt, txt | ✓ odt, docx, doc, rtf, fodt | OOXML + ODF + legacy OLE2 + RTF read |
| Save formats | full-fidelity | ◐ docx/odt keep paragraph props, run formatting and tables; find/replace + table-cell lossless | save_docx / save_odt write alignment/indent/spacing/shading/page-break/heading/list, run bold/italic/underline/size/color/hyperlink, and w:tbl with cell merges + shading; images still dropped |
| Character formatting | full | ✓ read + written back | bold, italic, underline, strike, color, highlight, font, size, super/subscript, caps — Run |
| Paragraph formatting | full | ✓ read | alignment, indent, spacing, shading, page breaks |
| Tables | full | ✓ read | cells, borders, colors, merges, row/col spans |
| Lists | full | ✓ read | nesting levels, ordered vs bullet |
| Images (inline) | full | ✓ read | inline_images |
| Headers / footers | full | ✓ read | headers_footers |
| Hyperlinks / bookmarks | full | ✓ read | hyperlinks_with_text, bookmark_text |
| Comments | full | ✓ read | comment_details |
| Footnotes / endnotes | full | ✓ read | footnotes |
| Content controls / form fields | full | ✓ read | content_controls |
| Styles | full catalog + edit | ◐ read catalog, not editable | distinct paragraph styles enumerated |
| Track changes | full accept/reject | ✓ read authors + accept / reject | revision_authors, accept_revision, reject_revision |
| Mail merge | full execute | ✓ fields extracted and executed | merge_fields enumerates; mail_merge substitutes a record into a copy of the document |
| In-place editing | full WYSIWYG | ◐ structural edit, not WYSIWYG | edit_paragraph / insert_paragraph / edit_table_cell / replace_lossless; no live layout-accurate editing surface |
| Page arranger | — (Word has no page sorter) | ✓ reorder pages | reorder_pages + the shared ZGui.arrange overlay in the desktop shell |
| TOC / references / citations | full | ◐ read, no generation | toc reads the TOC entries; bibliography reads citation sources; neither regenerates the field |
| Spell / grammar check | full | ◐ spell only, caller-supplied dictionary | spell_check — no bundled dictionaries, no grammar model |
| Macros (VBA) | full | ◐ modules extracted, not executed | ole2::vba_modules; no Basic interpreter |
| Structural merge / blame | — (opaque blob to git) | ✓ writer.merge3, writer.blame | git-native 3-way structural merge driver + per-paragraph revision attribution |
| Export | ✓ PDF, HTML, Markdown | writer.pdf, to_html/to_markdown |
PowerPoint → Impress
reads .pptx / .odp / .ppt / .fodp · engine: src/impress.rs
| Feature group | PowerPoint | zoffice Impress | Evidence / note |
|---|---|---|---|
| Open formats | pptx, ppt, odp | ✓ pptx, odp, ppt, fodp | OOXML + ODF + legacy binary read |
| Save formats | full-fidelity | ◐ pptx + odp text and positioned shapes | save_pptx / save_odp write each shape's text plus its x/y/w/h; masters, media and charts are not re-emitted |
| Slides | full | ✓ read + add blank | add_slide appends empty |
| Slide delete / reorder | full | ✓ delete + slide-sorter reorder | delete_slide (drops the slide with its notes), reorder_slides + the shared ZGui.arrange overlay |
| Layouts / masters | full + edit | ◐ read, not editable | layout_names, master_count |
| Placeholders | full | ✓ read | placeholders |
| Shapes | full + edit | ◐ read geometry + text; positioned shapes written back on save | x/y/w/h positioning read + written back (pptx + odp) |
| Text extraction | full | ✓ read | plain_text |
| Media (audio / video) | full | ✓ read | embedded clips per slide — media |
| Tables on slides | full | ✓ read | rows × columns |
| Speaker notes | full | ✓ read | per-slide notes |
| WordArt | full | ✓ read | text + warp preset |
| Charts | full | ◐ read + render, no edit | charts_render |
| Animations | full | ◐ read effect types, no edit | animations |
| Transitions | full | ◐ read effect types, no edit | transitions |
| SmartArt / diagrams | full | ◐ enumerated, not rendered | smartart extracts each dgm:pt node text; no diagram layout/render engine |
| Master editing | full | ○ absent (read-only) | — |
| Slideshow / presenter view | full | ◐ presenter data, no live show | presenter_view builds the presenter model (current + next slide text, notes, slide N of M); no full-screen present mode |
| Export | ✓ PDF, HTML, Markdown | impress.pdf |
Access → Base
reads .odb (embedded HSQLDB) · engine: src/base.rs
| Feature group | Access | zoffice Base | Evidence / note |
|---|---|---|---|
| Open formats | accdb, mdb | ◐ .odb only | no Access-native accdb/mdb reader |
| Table catalog + data | full | ✓ read (embedded HSQLDB) | list_tables, table_rows — INSERT rows from the HSQLDB script |
| SQL SELECT execution | full | ✓ over embedded store | query, run_query, run_query_with_params, run_saved_query |
| Schema / foreign keys | full | ✓ read | hsqldb_script → CREATE TABLE / FK; table_schema, table_constraints, relationships, indexes, views, triggers, sequences |
| Query designer | full visual | ◐ catalog + run, no designer | list_queries, query_definitions, run_saved_query |
| Forms / reports | full designer | ◐ catalog names + metadata only | list_forms_reports, component_metadata |
| External DSN / ODBC | full | ◐ catalog visible, not queryable | data_source parses the connection URI |
| Write (DDL / DML) | full | ○ parsed, never persisted | parse_dml reads INSERT / UPDATE / DELETE into a typed Dml; nothing writes an .odb back — the one remaining planned engine gap in Base |
zoffice extras (no direct MS app)
LibreOffice ships Draw and Math as standalone apps; Microsoft folds those roles into Publisher/Visio and Word's equation editor. zoffice implements both as read + export engines, plus two shell features Microsoft Office has no equivalent for.
| Capability | zoffice | Evidence / note |
|---|---|---|
| Draw (vector graphics) | ◐ read .odg + SVG export + save .odg with shape geometry, no in-place edit | shapes, layers, gradients, connectors; export_svg / save_odg (rect/ellipse/line/… with svg:x/y/w/h) |
| Math (formula editor) | ◐ read StarMath → MathML, no edit | math.render, to_starmath |
| Embedded terminal | ✓ PTY shell in-app | zpwr-embed-terminal; Office has none |
| Command palette | ✓ ⌘K fzf-ranked | commandRegistry() in webui/app.js; beyond Office "Tell me" |
Structural VCS (zmerge / zblame) | ✓ git merge driver + per-paragraph blame | writer.merge3, writer.blame, scripts/git-zoffice-merge; Office treats .docx as an opaque blob |
| Formula-graph analysis | ✓ critical path · blast radius · root cause | calc.critical_path, calc.impact_map, calc.cell_impact, calc.rootcause; Excel's Trace arrows are one hop |
| Page / slide arrangers | ✓ drag-reorder overlay | Document::reorder_pages + Presentation::reorder_slides, driven by the shared ZGui.arrange overlay; Word has no page sorter |
Cross-cutting
| Feature | MS Office | zoffice | Note |
|---|---|---|---|
| PDF export | full | ✓ all apps | pure-Rust PDF 1.4 writer (src/pdf.rs, base-14 Helvetica) — no external converter, no spawned process |
| Localization (i18n) | full | ✓ 27 locales | zpwr-i18n runtime; catalogs in crates/zpwr-i18n/i18n/ |
| Print dialog | full | ○ absent | PDF export only, no print UI |
| Save button (desktop app) | full | ✓ wired | office_save_text plus the per-app mutators among the shell's 169 registered Tauri commands |
| Cloud co-authoring | full | ○ absent | — |
| Macros / scripting (VBA) | full | ◐ modules extracted, not executed | ole2::vba_modules; no Basic interpreter |
| Package encryption | full | ✓ read + write | MS-OFFCRYPTO Agile + Standard (src/crypto.rs) and ODF package encryption (src/crypto_odf.rs), pure RustCrypto |
| Digital signatures | full | ✓ verify + sign (no signing UI) | src/dsig.rs — verify_part_digests (integrity), verify_signatures (RSA SignatureValue), verify_cert_chain, sign_ooxml / sign_odf; hand-rolled Canonical XML, no external C14N dep |
| Accessibility (screen reader) | full | ○ unverified | not audited in engine surface |
| Copilot / generative AI | present | ○ absent | MS Copilot state is past my knowledge cutoff — flagged, not independently verified |
Reading this audit
The tables describe an embeddable document engine, not a shipped consumer suite — zoffice-core exists to be linked into Rust/Tauri hosts and over a C ABI, so its center of gravity is parsing + rendering + narrow lossless edits, with full authoring deliberately downstream. Where a row reads ◐ read-only, the data model for that feature is fully parsed and available to a host; what is missing is a mutate-and-serialize path that preserves it. The realistic near-term arc is Tier 2 (lossless patch) widening to cover more edit operations before Tier 3 (full save) becomes fidelity-preserving. Two claims here are not source-grounded and are marked as such: the estimated parity percentages (directional), and Microsoft Copilot's current state (past knowledge cutoff).