The in-memory representation of a workbook.
A workbook holds every part from the source archive as raw bytes (the
parts map) plus a parsed view of the handful of parts ExVEx actually
reasons about (the content_types manifest, and eventually the
relationships graph, sheet list, shared strings, and stylesheet).
Parts that higher-level APIs have not yet parsed — worksheets not yet
accessed, custom XML, VBA binaries, extension data — pass through
untouched on save/2. This is how ExVEx preserves round-trip fidelity
without exhaustively modelling every OOXML schema.
Summary
Functions
Returns the parsed worksheet tree for path, parsing and caching it on
first access. Subsequent calls reuse the cached tree so bulk reads and
writes don't pay the parse cost repeatedly.
Produces a new workbook whose parts map has every in-memory parsed
sub-document (shared strings, styles) re-serialized and written back into
the raw parts map. Called by ExVEx.save/2 right before ZIP emission.
Updates the cached sheet for path and marks the sheet dirty so
flush/1 re-serializes it on save.
Projects a workbook back into the flat list of ZIP entries needed by
ExVEx.Packaging.Zip.write/2.
Types
@type t() :: %ExVEx.Workbook{ calc_dirty: boolean(), content_types: ExVEx.Packaging.ContentTypes.t(), dirty_sheet_paths: MapSet.t(String.t()), part_order: [String.t()], parts: %{required(String.t()) => binary()}, shared_strings: ExVEx.OOXML.SharedStrings.t() | nil, shared_strings_dirty: boolean(), shared_strings_path: String.t() | nil, sheet_trees: %{required(String.t()) => tuple()}, source_path: Path.t() | nil, styles: ExVEx.OOXML.Styles.t() | nil, styles_dirty: boolean(), styles_path: String.t() | nil, workbook: ExVEx.OOXML.Workbook.t(), workbook_path: String.t(), workbook_rels: ExVEx.Packaging.Relationships.t() }
Functions
@spec fetch_sheet_tree(t(), String.t()) :: {:ok, ExVEx.OOXML.Worksheet.Editable.t(), t()} | {:error, term()}
Returns the parsed worksheet tree for path, parsing and caching it on
first access. Subsequent calls reuse the cached tree so bulk reads and
writes don't pay the parse cost repeatedly.
Produces a new workbook whose parts map has every in-memory parsed
sub-document (shared strings, styles) re-serialized and written back into
the raw parts map. Called by ExVEx.save/2 right before ZIP emission.
@spec put_sheet_tree(t(), String.t(), ExVEx.OOXML.Worksheet.Editable.t()) :: t()
Updates the cached sheet for path and marks the sheet dirty so
flush/1 re-serializes it on save.
@spec to_entries(t()) :: [ExVEx.Packaging.Zip.Entry.t()]
Projects a workbook back into the flat list of ZIP entries needed by
ExVEx.Packaging.Zip.write/2.
Parts are written in original source order; any parts added after open/1
land at the end. Every part is emitted from its raw bytes in parts, so
untouched content is byte-preserved on round-trip.