ETS-backed editable representation of a worksheet. The parsed SimpleForm tree is converted on first access and materialised back to a tree at serialise time.
The cell grid lives in an ETS :set table for O(1) lookup and insert.
Surrounding <worksheet> content (<sheetViews>, <cols>,
<mergeCells>, <pageMargins>, …) passes through pre_sheet_data /
post_sheet_data unchanged so fidelity is preserved.
Sharing semantics
ETS tables are mutable. Two %ExVEx.Workbook{} references that share
the same cached sheet via Workbook.put_sheet_tree/3 also share the
same underlying ETS table; a mutation on one is visible from the other.
In practice this shows up between a workbook and its put_cell
descendants after the sheet has been parsed at least once. A pristine
workbook from ExVEx.open/1 that has not yet touched a sheet is
insulated because it will lazily create a fresh table on first access.
If you need an independent snapshot, ExVEx.save/2 it and open/1
that, or call ExVEx.close/1 and re-open.
Memory lifecycle
ETS tables persist until the owning process exits. In short-lived
processes (scripts, one-shot jobs, tests) this is fine. In long-running
servers that open many workbooks, call ExVEx.close/1 when done with a
workbook to reclaim the tables eagerly.
Summary
Functions
Returns the resolved %ExVEx.OOXML.Worksheet.Cell{} record for the given
coordinate, or :error if the cell is absent.
Drops the <dimension> element from the worksheet so Excel recomputes
the used range on open. No-op if the sheet has no <dimension>.
Applies a structural row/column shift to every populated cell on this
sheet. Cells in deletion spans are removed; surviving cells have their
coordinates rekeyed; formulas inside cells are rewritten via
ExVEx.Formula.Shift. Merged ranges in post_sheet_data are shifted
too.
Types
Functions
@spec cell_record_at(t(), ExVEx.Utils.Coordinate.t()) :: {:ok, ExVEx.OOXML.Worksheet.Cell.t()} | :error
Returns the resolved %ExVEx.OOXML.Worksheet.Cell{} record for the given
coordinate, or :error if the cell is absent.
@spec cells_map(t()) :: %{ required(ExVEx.Utils.Coordinate.t()) => ExVEx.OOXML.Worksheet.Cell.t() }
Drops the <dimension> element from the worksheet so Excel recomputes
the used range on open. No-op if the sheet has no <dimension>.
@spec get_cell(t(), ExVEx.Utils.Coordinate.t()) :: {:ok, cell_element()} | :error
@spec merge(t(), ExVEx.Utils.Range.t(), boolean()) :: t()
@spec merged_ranges(t()) :: [ExVEx.Utils.Range.t()]
@spec put_cell(t(), ExVEx.Utils.Coordinate.t(), ExVEx.cell_value()) :: t()
@spec set_cell_style(t(), ExVEx.Utils.Coordinate.t(), non_neg_integer()) :: t()
@spec shift(t(), ExVEx.Mutation.Shift.t(), String.t()) :: t()
Applies a structural row/column shift to every populated cell on this
sheet. Cells in deletion spans are removed; surviving cells have their
coordinates rekeyed; formulas inside cells are rewritten via
ExVEx.Formula.Shift. Merged ranges in post_sheet_data are shifted
too.
sheet_name is the name of the sheet this Editable represents, used
to scope formulas that reference the current sheet.
@spec unmerge(t(), ExVEx.Utils.Range.t()) :: t()