Skip to main content

WorkbookManager

Struct WorkbookManager 

Source
pub struct WorkbookManager {
    pub sheets: Vec<Sheet>,
    pub charts: Vec<Chart>,
    pub pivot_tables: Vec<PivotTable>,
    pub vba_project: Option<VbaProject>,
}
Expand description

A whole workbook: its sheets, charts, pivot tables and VBA project, and the operations that span more than one of them.

The entry point to this crate, and the layer an embedder should drive. Two behaviors are only correct at this level:

Editing the Sheets directly is allowed – the fields are public – but skips both, so cross-sheet formulas and pivot output go stale silently.

Fields§

§sheets: Vec<Sheet>

The worksheets, in workbook order. Cell coordinates within them are 0-based.

§charts: Vec<Chart>

The charts. Workbook-level rather than sheet-scoped; which sheet a chart is drawn on comes from its data_range.

§pivot_tables: Vec<PivotTable>

The pivot table definitions. Workbook-level, since a pivot’s source and destination may be on different sheets.

§vba_project: Option<VbaProject>

The VBA project, if the workbook has macros.

Implementations§

Source§

impl WorkbookManager

Source

pub fn run_macro( &mut self, module: Option<&str>, procedure: &str, args: &[&str], ) -> Result<RunOutcome, Error>

Runs one of this workbook’s own VBA procedures against this workbook.

Phase 2 of docs/vba-macro-support.md, and the entry point that separates it from Phase 1: the interpreter borrows the workbook for the duration, so a macro can read and write cells, walk the sheets, and call worksheet functions. run_macro stays as the text-only form – it is what visi_core.run_macro and fuzz/fuzz_vba.py drive, and a macro that touches no workbook has no reason to need one.

module picks which module to take the procedure from; None searches every module for one that declares it, which is the common single-module case. Resolving it here rather than in each caller is Runs a VBA procedure in the workbook’s project.

The workbook is left recalculated, so a caller that saves afterwards writes the values the macro itself would have read.

Source

pub fn run_open_events(&mut self) -> Result<RunOutcome, Error>

Runs startup macro events (Workbook_Open in ThisWorkbook then Auto_Open in standard modules).

Source§

impl WorkbookManager

Source

pub fn load_bytes(buffer: &[u8]) -> Result<Self>

Load Excel workbook from bytes buffer

Source

pub fn save_bytes(&self) -> Result<Vec<u8>>

Serialize the workbook to .xlsx bytes.

The byte-level counterpart to Self::load_bytes. Callers that want to read or write an actual file supply their own IO – the visi CLI does so through its WorkbookFile trait.

Source

pub fn new_empty() -> Result<Self>

A new workbook containing a single empty sheet named Sheet1.

Source

pub fn evaluate(&mut self) -> Result<()>

Recalculate all formulas in all sheets using visi-core engine

Source

pub fn find_sheet_index(&self, name_opt: Option<&str>) -> Result<usize>

Find index of sheet by name, or return default index 0 if name is None.

Source

pub fn get_summary(&self, file_name: &str) -> WorkbookSummary

Get structural summary of workbook

Source

pub fn ensure_capacity( &mut self, sheet_idx: usize, target_row: usize, target_col: usize, )

Ensure sheet bounds can accommodate specified target_row and target_col

Source

pub fn set_cell_style( &mut self, sheet_name: Option<&str>, row: usize, col: usize, style: CellStyle, ) -> Result<()>

Merges style into one cell’s existing style.

Row and column are 0-based, like every other coordinate on this type. A1 notation is a CLI/parser-boundary concern: callers holding a string like "Sheet2!B3" parse it themselves and resolve the sheet prefix against sheet_name before calling in.

Source

pub fn set_range_style( &mut self, sheet_name: Option<&str>, start_row: usize, start_col: usize, end_row: usize, end_col: usize, style: CellStyle, ) -> Result<()>

Merges style into every cell of an inclusive 0-based range.

Source

pub fn get_cell_style( &self, sheet_name: Option<&str>, row: usize, col: usize, ) -> Result<Option<CellStyle>>

The style applied to one 0-based cell, if it has one.

Source

pub fn set_table_style( &mut self, table_name: &str, style_name: &str, ) -> Result<()>

Sets an Excel Table’s visual style, looking the table up by name across every sheet.

§Errors

Error::NotFound if no table in the workbook has that name.

Source

pub fn get_table_style(&self, table_name: &str) -> Result<Option<String>>

An Excel Table’s visual style, or None if it has none set.

§Errors

Error::NotFound if no table in the workbook has that name.

Source

pub fn set_cell( &mut self, sheet_idx: usize, row: usize, col: usize, value: String, )

Update cell source / value at (row, col)

Source

pub fn insert_row(&mut self, sheet_idx: usize, row_idx: usize) -> Result<()>

Insert row at 0-based index.

Formulas throughout the workbook are rewritten to follow the cells that moved, as in Excel, and Excel Table and pivot ranges move with the cells they cover. See core::grid_edit for the rules.

Source

pub fn delete_row(&mut self, sheet_idx: usize, row_idx: usize) -> Result<()>

Delete row at 0-based index.

References to the deleted row become #REF! and references below it move up, as in Excel.

Source

pub fn insert_col(&mut self, sheet_idx: usize, col_idx: usize) -> Result<()>

Insert column at 0-based index.

Source

pub fn delete_col(&mut self, sheet_idx: usize, col_idx: usize) -> Result<()>

Delete column at 0-based index.

Source

pub fn insert_cells_shift_down( &mut self, sheet_idx: usize, row: usize, first_col: usize, last_col: usize, count: usize, ) -> Result<()>

Excel’s Insert cells, shift down over an inclusive column band, with the workbook-wide formula rewrite that goes with it.

This is what ListRows.Add is: only first_col..=last_col move, so a formula beside the band stays put while one inside it shifts. See core::grid_edit’s band field for the reference rules, which are measured rather than assumed.

Source

pub fn delete_cells_shift_up( &mut self, sheet_idx: usize, row: usize, first_col: usize, last_col: usize, count: usize, ) -> Result<()>

Excel’s Delete cells, shift up over an inclusive column band; the inverse of WorkbookManager::insert_cells_shift_down.

Source

pub fn add_sheet(&mut self, name: &str) -> Result<()>

Add new sheet with specified name

Source

pub fn delete_sheet(&mut self, name: &str) -> Result<()>

Delete sheet by name

Source

pub fn rename_sheet(&mut self, old_name: &str, new_name: &str) -> Result<()>

Rename sheet

Source

pub fn add_chart( &mut self, sheet_name: &str, chart_type: ChartType, range: String, title: Option<String>, anchor: Option<(usize, usize)>, ) -> Result<u64>

Add chart to workbook

Source

pub fn edit_chart( &mut self, id: u64, name: Option<String>, chart_type: Option<ChartType>, data_range: Option<String>, title: Option<Option<String>>, xlabel: Option<Option<String>>, ylabel: Option<Option<String>>, show_legend: Option<bool>, anchor: Option<(usize, usize)>, ) -> Result<()>

Edit an existing chart’s properties. Every parameter is optional; None leaves that field unchanged. title/xlabel/ylabel are tri-state (Option<Option<String>>): outer None leaves the field unchanged, Some(None) clears it, Some(Some(text)) sets it.

Source

pub fn has_vba_project(&self) -> bool

Whether the workbook carries a VBA project.

Source

pub fn list_vba_modules(&self) -> Vec<&VbaModule>

Lists every module in the workbook’s VBA project, if it has one.

Source

pub fn ensure_vba_project(&mut self) -> Result<()>

Creates an empty, entirely synthetic VBA project (see VbaProject::new_empty) if this workbook doesn’t already have one. Idempotent.

Source

pub fn add_vba_module( &mut self, name: String, kind: VbaModuleKind, source: String, bound_sheet_id: Option<u64>, ) -> Result<()>

Adds a new module to the workbook’s VBA project (creating the project from the bundled template first, if needed). bound_sheet_id is required for VbaModuleKind::Document (except when name is "ThisWorkbook", which – like real Excel’s own always-present ThisWorkbook module – isn’t tied to a specific sheet; any bound_sheet_id passed alongside it is ignored rather than stored) – note this does NOT rename the sheet, or vice versa; Excel allows a document module’s own name and its sheet’s display name to diverge, and this codebase deliberately doesn’t cascade one into the other.

Source

pub fn remove_vba_module(&mut self, name: &str) -> Result<()>

Removes a VBA module by name, matched case-insensitively.

§Errors

Error::Vba if the workbook has no VBA project, or Error::NotFound if it has no module by that name.

Source

pub fn rename_vba_module( &mut self, old_name: &str, new_name: &str, ) -> Result<()>

Renames a VBA module.

Renames only the module; VBA source that calls into it is not rewritten, so a module referenced by name elsewhere will no longer resolve.

§Errors

Error::InvalidName if new_name is not a valid VBA identifier, Error::AlreadyExists if another module already has it, Error::Vba if the workbook has no VBA project, or Error::NotFound if it has no module called old_name.

Source

pub fn set_vba_module_source( &mut self, name: &str, source: String, ) -> Result<()>

Replaces a VBA module’s source text.

The caller supplies the whole module body, including its Attribute VB_Name = "..." line, matching how real Excel-authored module streams are shaped.

§Errors

Error::Vba if the workbook has no VBA project, or Error::NotFound if it has no module by that name.

Source

pub fn delete_chart(&mut self, id: u64) -> Result<()>

Delete chart by u64 ID

Source

pub fn find_table(&self, name: &str) -> Option<(&Sheet, &ExcelTable)>

Find the sheet that owns the table with the given name, and the table itself. Table names are unique across the whole workbook.

Source

pub fn list_tables(&self) -> Vec<(&str, &ExcelTable)>

List every table in the workbook, alongside the name of the sheet it lives on.

Source

pub fn add_table( &mut self, sheet_name: Option<&str>, name: &str, start_row: usize, start_col: usize, end_row: usize, end_col: usize, has_header_row: bool, has_totals_row: bool, ) -> Result<u64>

Define a new Excel Table over an existing cell range on a sheet. Table names are unique across the entire workbook (not just the sheet), matching how Excel itself scopes structured-reference names.

Source

pub fn delete_table(&mut self, name: &str) -> Result<()>

Delete a table by name (leaves the underlying cell contents alone).

Source

pub fn rename_table(&mut self, old_name: &str, new_name: &str) -> Result<()>

Rename a table.

Source

pub fn resize_table( &mut self, name: &str, new_end_row: usize, new_end_col: usize, ) -> Result<()>

Resize a table by moving its bottom-right corner.

Source

pub fn rename_table_column( &mut self, table_name: &str, col_index: usize, new_name: &str, ) -> Result<()>

Rename one column (0-based, relative to the table) of a table.

Source

pub fn find_pivot_table(&self, name: &str) -> Option<&PivotTable>

Find a pivot table by name (case-insensitive).

Source

pub fn list_pivot_tables(&self) -> &[PivotTable]

List every pivot table in the workbook.

Source

pub fn add_pivot_table_from_table( &mut self, name: &str, source_table_name: &str, dest_sheet_name: Option<&str>, dest_row: usize, dest_col: usize, grand_totals_row: bool, grand_totals_col: bool, ) -> Result<u64>

Defines a new pivot table sourced from an existing Excel Table, with no fields assigned yet – mirroring Excel inserting an empty PivotTable shell that fills in as fields are added to it.

Source

pub fn add_pivot_table_from_range( &mut self, name: &str, source_sheet_name: Option<&str>, start_row: usize, start_col: usize, end_row: usize, end_col: usize, dest_sheet_name: Option<&str>, dest_row: usize, dest_col: usize, grand_totals_row: bool, grand_totals_col: bool, ) -> Result<u64>

Defines a new pivot table sourced from a plain cell range (its first row is treated as column headers), with no fields assigned yet.

Source

pub fn delete_pivot_table(&mut self, name: &str) -> Result<()>

Deletes a pivot table definition and clears its last rendered output range (leaves the source data untouched).

Source

pub fn rename_pivot_table( &mut self, old_name: &str, new_name: &str, ) -> Result<()>

Renames a pivot table (names are unique workbook-wide, like tables).

Source

pub fn add_pivot_field( &mut self, pivot_name: &str, area: PivotArea, column: &str, aggregation: Option<PivotAggregation>, ) -> Result<()>

Adds a field to one of a pivot table’s four areas (Row/Column/ Value/Filter) and immediately refreshes its output, mirroring Excel’s live-updating field list.

A field can only occupy one area at a time, exactly like dragging a field to a new area in Excel’s field list moves it rather than duplicating it (confirmed via the win32com driver: setting PivotField.Orientation a second time relocates the field). Value fields are the one exception – Excel allows the same source column to appear as multiple value fields simultaneously (e.g. both “Sum of Amount” and “Min of Amount”), so adding to PivotArea::Value does not evict the column from Row/Column/Filter, and vice versa a Row/Column/Filter add does not evict existing value fields.

Source

pub fn remove_pivot_field( &mut self, pivot_name: &str, area: PivotArea, column: &str, ) -> Result<()>

Removes a field from one of a pivot table’s four areas and refreshes its output.

Source

pub fn set_pivot_filter( &mut self, pivot_name: &str, column: &str, values: Option<Vec<String>>, ) -> Result<()>

Restricts (or clears, with values: None) a filter field’s allowed values and refreshes the pivot table’s output.

Source

pub fn refresh_pivot_table(&mut self, pivot_name: &str) -> Result<()>

Recomputes a pivot table’s aggregation and re-materializes it as plain values onto its destination sheet. Like Excel, a pivot table only updates on an explicit refresh, never automatically as its source data changes.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V