Python API
The Python package exposes a Pythonic wrapper over the Formulon C ABI compiled to formulon_capi.wasm. The published wheel is py3-none-any; pip installs wasmtime as the platform runtime.
Glossary: py3-none-any wheel
A Python wheel with no Python ABI tag, no platform tag, and no native code. It supports CPython 3.9 and later where a compatible wasmtime wheel is available. The platform-specific runtime is supplied by wasmtime, not by formulon.
Top-level API
The module functions (formulon.eval_formula, formulon.error_display_name, formulon.merge_function_metadata, formulon.library_version, its alias formulon.version_string, and formulon.set_log_min_level) are listed with the workbook methods under Functions and methods. formulon.__version__ is the installed package version. set_log_min_level() is process-wide: the default LogLevel.OFF is silent, WARN or below writes one JSON record per line to stderr, and Python has no log-sink callback. The main types are Workbook, the Value record with its ValueKind enum, and FormulonError for host-side failures.
The package also exports the binding enums and the dataclass records used by workbook methods (Cell, Comment, ConditionalFormat, DataValidation, PaginationResult, PivotLayout, Theme, and others; formulon.__all__ lists them):
| Area | Enums |
|---|---|
| Values | ErrorCode (NULL = 0, DIV0 = 1, … UNKNOWN = 16) |
| Geometry and display | GeometryMode (DISPLAY = 0, PRINT = 1), DisplayStatus (OK = 0, OVERFLOW = 1, INVALID_FORMAT = 2) |
| AutoFilter | FilterKind, FilterOperator, DynamicFilterType, SortBy, SortMethod, DateTimeGrouping |
| Validation | ValidationErrorStyle (STOP = 0, WARNING = 1, INFORMATION = 2) |
| Themes and styles | ColorContext, ColorResolution, ThemeSource, EffectiveStyleSource |
| Images and drawings | ImageFormat, DrawingObjectKind, AnchorKind, AnchorEditAs |
| PivotTables | PivotAxis, PivotAggregation, PivotShowValuesAs, PivotFilterType, PivotFilterValueKind, PivotDateGrouping, PivotCalendar, PivotReportLayout, PivotCellKind |
| Text collation | CollationStrength (COMPARE = 0, DYNAMIC = 1, CLASSIC_EXACT = 2) |
| Workbook state | CalcMode, SheetVisibility, WorkbookFormat, ExternalLinkKind |
| Logging | LogLevel (DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3, OFF = 4) |
The function catalog is split by responsibility. Workbook.function_metadata(name) returns structural fields only (canonical name, arity, availability); the human-readable signature and description are None. Use the profile-based helpers for Excel display names and formula text, and use merge_function_metadata() with a host-owned BCP-47 UI locale for translated descriptions.
Workbook
from formulon import Workbook
with Workbook.create_default() as wb:
wb.set_formula(0, 0, 0, "=SUM(1,2,3)")
wb.recalc()
print(wb.get_value(0, 0, 0).to_python())create_default() builds the ordinary one-sheet workbook with Calibri 11. create_for_profile(profile_id) records the selected profile and applies its new-workbook defaults: body and optional phonetic fonts, the localized Normal style and first-sheet names, cell-xf alignment, phonetic settings, page margins, and the Mac row-height and base-column-width values. It writes no theme part, so a fresh workbook reads as using the default Office theme; Windows row and column metrics use the engine defaults.
Profile and formula-text helpers are workbook-independent static methods:
from formulon import Workbook
profile = "mac-365-de_DE"
shown = Workbook.localize_formula("=SUM(1.5,TRUE)", profile)
stored = Workbook.canonicalize_formula(shown, profile)
facts = Workbook.locale_facts(profile)
print(shown, stored, facts.decimal_separator, facts.true_name)localize_function_name() / canonicalize_function_name() map one function name. localize_formula() rewrites function names, list and array separators, decimal points, Boolean names, and error names while preserving strings, quoted sheet names, external qualifiers, and structured-reference brackets. canonicalize_formula() reverses that text rewrite. These helpers use the full profile id, not a numeric locale code, and they do not validate or install a formula. The profile catalog has 28 ids; locale facts are measured for every mac-* profile and win-365-ja_JP, while the other 13 Windows profiles use estimated locale data. LocaleFacts.collation_measured is separate and is true only for mac-* profiles.
Workbook.compare_text(a, b, strength, profile_id) returns -1, 0, or 1. Workbook.collation_classes(values, strength, profile_id) returns CollationClasses(class_ids, class_count): one dense id per Value, ascending in SORT order and meaningful only within that call. Text collation defines each CollationStrength fold and the class rules.
from formulon import CollationStrength, Value, ValueKind, Workbook
profile = "mac-365-en_US"
order = Workbook.compare_text("a", "b", CollationStrength.COMPARE, profile)
values = [Value(kind=ValueKind.TEXT, text="A"), Value(kind=ValueKind.TEXT, text="a")]
classes = Workbook.collation_classes(values, CollationStrength.DYNAMIC, profile)
print(order, classes.class_ids, classes.class_count)Functions and methods
Generated from the package type stubs (formulon/__init__.pyi) and the docstrings of the formulon source tree. Names starting with formulon. are module functions, names starting with Workbook. are class or static methods, and every other name is a Workbook instance method; is_valid is a property. = ... marks a parameter with a default, as in the stubs. A summary is the first sentence of the docstring. Workbook is also a context manager: leaving the with block calls close().
Reference source
These tables are generated from the core source for documentation target 0.18.0. The source commit is pinned so WASM, Python, and C declarations describe the same revision. Demos use published packages and display their runtime version separately.
Library, diagnostics and logging
| Name | Signature | Description |
|---|---|---|
formulon.library_version | library_version() -> str | Return the version string baked into the loaded WASM module. |
formulon.version_string | version_string() -> str | Alias of library_version(). |
formulon.error_display_name | error_display_name(error_code: int) -> str | Return an Excel literal such as "#DIV/0!" for an error code. |
formulon.set_log_min_level | set_log_min_level(level: Union[LogLevel, int]) -> None | Set the engine's minimum structured-log severity. |
Workbook lifecycle and I/O
| Name | Signature | Description |
|---|---|---|
Workbook.create_default | create_default() -> Workbook | Build a default workbook (a single sheet named Sheet1). |
Workbook.create_for_profile | create_for_profile(profile_id: str) -> Workbook | Build a new workbook with the defaults of an Excel profile. |
Workbook.create_empty | create_empty() -> Workbook | Build an empty workbook (no sheets). |
Workbook.load | load(data: Union[bytes, bytearray, memoryview]) -> Workbook | Load a workbook from an in-memory byte buffer. |
close | close() -> None | Release the underlying handle. |
is_valid | is_valid: bool | True while the handle is still alive. |
memory_usage | memory_usage() -> int | Return an estimate of the workbook's heap footprint, in bytes. |
save | save() -> bytes | Serialise the workbook to an in-memory .xlsx byte stream. |
save_as | save_as(fmt: Union[WorkbookFormat, int]) -> bytes | Serialise the workbook to an in-memory byte stream in fmt. |
save_with_diagnostics | save_with_diagnostics(fmt: Union[WorkbookFormat, int]) -> SaveDiagnostics | Serialise the workbook and return what the save cost. |
read_diagnostics | read_diagnostics() -> ReadDiagnostics | Return the loss counters captured when this workbook was loaded. |
iter_passthrough | iter_passthrough() -> Iterator[PassthroughPart] | Iterate over passthrough OOXML part paths. |
Sheets and structure
| Name | Signature | Description |
|---|---|---|
sheet_count | sheet_count() -> int | Number of sheets in the workbook. |
active_sheet | active_sheet() -> int | Index of the active sheet (activeTab of the first workbook view). |
set_active_sheet | set_active_sheet(index: int) -> None | Mark the sheet at index active so save records it. |
sheet_name | sheet_name(index: int) -> str | Display name (UTF-8) of the sheet at index. |
add_sheet | add_sheet(name: str) -> None | Append a new sheet with the given UTF-8 display name. |
move_sheet | move_sheet(from_index: int, to_index: int) -> None | Move the sheet at from_index to to_index (post-removal). |
remove_sheet | remove_sheet(index: int) -> None | Remove the sheet at index. |
rename_sheet | rename_sheet(index: int, new_name: str) -> None | Rename the sheet at index to new_name. |
insert_rows | insert_rows(sheet: int, row: int, count: int) -> None | Insert count rows at row on sheet. |
delete_rows | delete_rows(sheet: int, row: int, count: int) -> None | Delete count rows starting at row on sheet. |
insert_cols | insert_cols(sheet: int, col: int, count: int) -> None | Insert count columns at col on sheet. |
delete_cols | delete_cols(sheet: int, col: int, count: int) -> None | Delete count columns starting at col on sheet. |
Cells
| Name | Signature | Description |
|---|---|---|
set_number | set_number(sheet: int, row: int, col: int, value: float) -> None | Store the number value at (sheet, row, col). |
set_bool | set_bool(sheet: int, row: int, col: int, value: bool) -> None | Store the boolean value at (sheet, row, col). |
set_error | set_error(sheet: int, row: int, col: int, error_code: int) -> None | Store an Excel cell error at (sheet, row, col). |
set_text | set_text(sheet: int, row: int, col: int, value: str) -> None | Store the string value at (sheet, row, col). |
set_blank | set_blank(sheet: int, row: int, col: int) -> None | Clear the cell at (sheet, row, col). |
set_formula | set_formula(sheet: int, row: int, col: int, formula: str) -> None | Store the formula formula at (sheet, row, col). |
set_phonetic | set_phonetic(sheet: int, row: int, col: int, text: str) -> None | Set the cell's phonetic guide (OOXML <rPh>, furigana). |
set_phonetic_runs | set_phonetic_runs(sheet: int, row: int, col: int, runs: Sequence[PhoneticRun]) -> None | Set the cell's phonetic guide as one <rPh> block per run. |
get_phonetic | get_phonetic(sheet: int, row: int, col: int) -> str | Return the cell's phonetic guide, or "" when it has none. |
get_phonetic_runs | get_phonetic_runs(sheet: int, row: int, col: int) -> List[PhoneticRun] | Return the cell's <rPh> blocks, spans included. |
set_phonetic_properties | set_phonetic_properties(sheet: int, row: int, col: int, properties: PhoneticProperties) -> None | Set how the cell's phonetic guide renders. |
get_phonetic_properties | get_phonetic_properties(sheet: int, row: int, col: int) -> PhoneticProperties | Return how the cell's phonetic guide renders. |
has_phonetic_properties | has_phonetic_properties(sheet: int, row: int, col: int) -> bool | Whether the cell's phonetic properties are explicit. |
get_value | get_value(sheet: int, row: int, col: int) -> Value | Read the cached value at (sheet, row, col). |
lambda_text_at | lambda_text_at(sheet: int, row: int, col: int) -> str | Render the lambda cached at (sheet, row, col) as text. |
iter_cells | iter_cells(sheet: int) -> Iterator[Cell] | Iterate over every written coordinate on sheet. |
get_formula | get_formula(sheet: int, row: int, col: int) -> Optional[str] | Return the stored A1 formula (leading = included), or None for a non-formula cell. |
get_formula_r1c1 | get_formula_r1c1(sheet: int, row: int, col: int) -> Optional[str] | Return the formula in R1C1 notation relative to the cell, or None for a non-formula cell. |
get_cells_in_range | get_cells_in_range(sheet: int, cell_range: MergeRange, cursor: Optional[int] = ..., limit: Optional[int] = ...) -> Tuple[List[Cell], Optional[int]] | Return one page of the populated cells in cell_range (row-major). |
Recalculation
| Name | Signature | Description |
|---|---|---|
recalc | recalc() -> None | Drive a full incremental recalc. |
set_iterative | set_iterative(enabled: bool, max_iterations: int, max_change: float) -> None | Configure iterative calculation. |
set_iterative_enabled | set_iterative_enabled(enabled: bool) -> None | Toggle iterative calculation, keeping the cap and threshold. |
get_iterative | get_iterative() -> IterativeSettings | Read back the iterative-calculation settings. |
partial_recalc | partial_recalc(sheet: int, first_row: int, last_row: int, first_col: int, last_col: int) -> int | Recalc the dependency closure for a viewport; return cell count. |
calc_mode | calc_mode() -> CalcMode | Return the workbook's calc mode (round-trip metadata). |
full_precision | full_precision() -> bool | Return <calcPr fullPrecision>; false is "set precision as displayed" (metadata only). |
set_full_precision | set_full_precision(full_precision: bool) -> None | Set <calcPr fullPrecision>. |
calc_on_save | calc_on_save() -> bool | Return <calcPr calcOnSave> (default true). |
set_calc_on_save | set_calc_on_save(calc_on_save: bool) -> None | Set <calcPr calcOnSave>. |
ref_mode | ref_mode() -> RefMode | Return <calcPr refMode>: the reference notation formulas are shown in. |
set_ref_mode | set_ref_mode(mode: Union[RefMode, int]) -> None | Set <calcPr refMode>. |
date1904 | date1904() -> bool | Return whether the workbook uses the 1904 date system. |
set_date1904 | set_date1904(date1904: bool) -> None | Switch the date system. |
set_calc_mode | set_calc_mode(mode: Union[CalcMode, int]) -> None | Set the workbook's calc mode. |
pinned_now | pinned_now() -> Optional[CivilTime] | Return the pinned wall-clock reading, or None when the |
set_pinned_now | set_pinned_now(year: int, month: int, day: int, hour: int = ..., minute: int = ..., second: int = ...) -> None | Pin every clock-dependent result to one instant. |
clear_pinned_now | clear_pinned_now() -> None | Release the pin so clock-dependent results follow the host clock |
add_data_table | add_data_table(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int, *, row_input: Optional[Tuple[int, int]] = ..., col_input: Optional[Tuple[int, int]] = ...) -> None | Create a data table whose result range is first_row..last_col (0-based, inclusive). |
get_data_table | get_data_table(sheet: int, row: int, col: int) -> Optional[DataTable] | Return the data table whose result range contains (row, col), or None. |
remove_data_table | remove_data_table(sheet: int, row: int, col: int) -> None | Remove the data table containing (row, col) and blank its result cells. |
recalc_data_tables | recalc_data_tables() -> None | Recompute every data table now, whatever the calc mode (the explicit calculation of AUTO_NO_TABLE). |
Read-only evaluation
| Name | Signature | Description |
|---|---|---|
evaluate_formula_array | evaluate_formula_array(sheet: int, row: int, col: int, formula: str) -> List[List[Value]] | Evaluate formula as if entered at (sheet, row, col) and |
evaluate_cf_formula | evaluate_cf_formula(sheet: int, row: int, col: int, anchor_row: int, anchor_col: int, formula: str) -> bool | Evaluate a conditional-format formula at one cell without mutation. |
formulon.eval_formula | eval_formula(formula: str) -> Value | Evaluate a single formula against a fresh, default workbook. |
Profiles, locale and text
| Name | Signature | Description |
|---|---|---|
formulon.merge_function_metadata | merge_function_metadata(base: FunctionMetadata, entry: Optional[Mapping[str, object]], locale: str) -> Union[FunctionMetadata, MergedFunctionMetadata] | Merge a host-supplied entry over the engine result base. |
excel_profile_id | excel_profile_id() -> ExcelProfileId | Return the active Excel formula profile id. |
set_excel_profile_id | set_excel_profile_id(profile_id: ExcelProfileId) -> None | Set the workbook's Excel formula profile by id. |
Workbook.function_count | function_count() -> int | Return the total number of registered Formulon functions. |
Workbook.function_name_at | function_name_at(index: int) -> str | Return the canonical name of the index-th function. |
Workbook.function_metadata | function_metadata(name: str) -> Optional[FunctionMetadata] | Return metadata for name or None when unknown. |
Workbook.localize_function_name | localize_function_name(canonical_name: str, profile_id: ExcelProfileId) -> str | Return the display name of canonical_name under profile_id. |
Workbook.canonicalize_function_name | canonicalize_function_name(localized_name: str, profile_id: ExcelProfileId) -> str | Return the canonical English name for localized_name under profile_id. |
Workbook.localize_formula | localize_formula(formula: str, profile_id: ExcelProfileId) -> str | Rewrite stored (en-invariant) formula text into profile_id's spelling. |
Workbook.canonicalize_formula | canonicalize_formula(formula: str, profile_id: ExcelProfileId) -> str | Rewrite profile_id-spelled formula text into the en-invariant form. |
Workbook.locale_facts | locale_facts(profile_id: ExcelProfileId) -> LocaleFacts | Return the locale facts (separators, names, currency, error names) of profile_id. |
Workbook.compare_text | compare_text(a: str, b: str, strength: CollationStrength, profile_id: ExcelProfileId) -> int | Compare two texts under the collation of profile_id. |
Workbook.collation_classes | collation_classes(values: Sequence[Value], strength: CollationStrength, profile_id: ExcelProfileId) -> CollationClasses | Classify values into collation-ordered equivalence classes. |
Defined names
| Name | Signature | Description |
|---|---|---|
set_defined_name | set_defined_name(name: str, formula: str) -> None | Set, append, or remove a workbook-scoped defined name. |
set_defined_name_scoped | set_defined_name_scoped(name: str, formula: str, local_sheet_id: int) -> None | Set, append, or remove a defined name in workbook or sheet scope. |
set_defined_name_attrs | set_defined_name_attrs(name: str, local_sheet_id: int = ..., *, comment: Optional[str] = ..., hidden: Optional[bool] = ...) -> None | Set the comment and / or hidden attribute of an existing defined name. |
iter_defined_names | iter_defined_names() -> Iterator[DefinedName] | Iterate over every defined name in declaration order. |
Tables
| Name | Signature | Description |
|---|---|---|
iter_tables | iter_tables() -> Iterator[Table] | Iterate over every table in declaration order. |
table_create | table_create(sheet: int, ref: str, name: str, display_name: str, column_names: Sequence[str], style_name: str = ..., header_row: bool = ..., totals_row: bool = ..., *, show_first_column: Optional[bool] = ..., show_last_column: Optional[bool] = ..., show_row_stripes: Optional[bool] = ..., show_column_stripes: Optional[bool] = ...) -> int | Create a worksheet table and return its index. |
table_set_style_info | table_set_style_info(index: int, style_name: Optional[str], show_first_column: bool = ..., show_last_column: bool = ..., show_row_stripes: bool = ..., show_column_stripes: bool = ...) -> None | Set the table's style name and toggles, making the style element present. |
table_rename | table_rename(index: int, name: str, display_name: Optional[str] = ...) -> None | Rename table index; display_name=None uses name for both. |
table_set_column_totals | table_set_column_totals(index: int, column: int, function: Optional[str] = ..., label: Optional[str] = ..., formula: Optional[str] = ...) -> None | Set column column's totals-row function and label. |
table_update | table_update(index: int, ref: str, style_name: Optional[str] = ..., header_row: Optional[bool] = ..., totals_row: Optional[bool] = ..., *, name: Optional[str] = ..., display_name: Optional[str] = ..., show_first_column: Optional[bool] = ..., show_last_column: Optional[bool] = ..., show_row_stripes: Optional[bool] = ..., show_column_stripes: Optional[bool] = ...) -> None | Replace a table's range and optional visual style. |
table_remove | table_remove(index: int) -> None | Remove the table at index. |
table_style_count | table_style_count() -> int | Return the number of custom table / PivotTable styles. |
get_table_style | get_table_style(index: int) -> TableStyle | Return the custom table style at index. |
set_table_style | set_table_style(style: TableStyle) -> None | Add a custom table style, or replace the one with the same name. |
remove_table_style | remove_table_style(name: str) -> None | Remove the custom table style name. |
table_style_defaults | table_style_defaults() -> Tuple[str, str] | Return the default (table_style, pivot_style) names; empty when unset. |
set_table_style_defaults | set_table_style_defaults(table_style: Optional[str] = ..., pivot_style: Optional[str] = ...) -> None | Set the default style names; None keeps one, "" removes it. |
Dependencies, spills and external links
| Name | Signature | Description |
|---|---|---|
precedents | precedents(sheet: int, row: int, col: int, depth: int = ...) -> List[CellNode] | Return the cells (sheet, row, col) reads (up to depth). |
dependents | dependents(sheet: int, row: int, col: int, depth: int = ...) -> List[CellNode] | Return the cells that read (sheet, row, col) (up to depth). |
spill_info | spill_info(sheet: int, row: int, col: int) -> SpillInfo | Return dynamic-array spill info for (sheet, row, col). |
external_link_count | external_link_count() -> int | Return the number of external-link records on the workbook. |
get_external_link_at | get_external_link_at(index: int) -> ExternalLink | Read the index-th external-link record. |
get_external_links | get_external_links() -> List[ExternalLink] | Return every external-link record in document order. |
Sheet view and protection
| Name | Signature | Description |
|---|---|---|
get_show_phonetic | get_show_phonetic(sheet: int, row: int, col: int) -> bool | Whether the cell shows its phonetic guide (<c ph="1">). |
set_show_phonetic | set_show_phonetic(sheet: int, row: int, col: int, show: bool) -> None | Set the cell's "Show Phonetic" display flag. |
get_workbook_protection | get_workbook_protection() -> WorkbookProtection | Read the workbook's <workbookProtection>; every field is false, empty or zero when absent. |
set_workbook_protection | set_workbook_protection(protection: WorkbookProtection) -> None | Replace the modelled <workbookProtection> attributes; an all-empty record removes the element. |
protected_range_count | protected_range_count(sheet: int) -> int | Return the number of protected ranges on sheet. |
get_protected_ranges | get_protected_ranges(sheet: int) -> List[ProtectedRange] | Return the protected ranges of sheet in file order. |
add_protected_range | add_protected_range(sheet: int, protected: ProtectedRange) -> None | Append a protected range; name must be non-empty and unique on the sheet. |
update_protected_range | update_protected_range(sheet: int, index: int, protected: ProtectedRange) -> None | Replace the index-th protected range of sheet. |
remove_protected_range | remove_protected_range(sheet: int, index: int) -> None | Remove the index-th protected range of sheet. |
get_sheet_protection | get_sheet_protection(sheet: int) -> SheetProtection | Read the sheet's <sheetProtection> flags. |
set_sheet_protection | set_sheet_protection(sheet: int, protection: SheetProtection) -> None | Replace the sheet's <sheetProtection> flags wholesale. |
get_sheet_view | get_sheet_view(sheet: int) -> SheetView | Read the full per-sheet view (zoom, freeze, tab-hidden, and the |
set_sheet_zoom | set_sheet_zoom(sheet: int, zoom_scale: int) -> None | Set the sheet zoom percentage (clamped to [10, 400]). |
set_sheet_freeze | set_sheet_freeze(sheet: int, freeze_rows: int, freeze_cols: int) -> None | Set the frozen pane in (rows, cols). |
set_sheet_tab_hidden | set_sheet_tab_hidden(sheet: int, hidden: bool) -> None | Set the sheet tab's hidden flag. |
set_sheet_visibility | set_sheet_visibility(sheet: int, visibility: Union[SheetVisibility, int]) -> None | Set the sheet tab's visibility to one of the three states. |
set_sheet_show_grid_lines | set_sheet_show_grid_lines(sheet: int, show: bool) -> None | Set the sheet's showGridLines flag. |
set_sheet_show_row_col_headers | set_sheet_show_row_col_headers(sheet: int, show: bool) -> None | Set the sheet's showRowColHeaders flag. |
set_sheet_show_zeros | set_sheet_show_zeros(sheet: int, show: bool) -> None | Set the sheet's showZeros flag. |
set_sheet_show_formulas | set_sheet_show_formulas(sheet: int, show: bool) -> None | Set the sheet's showFormulas flag. |
set_sheet_show_outline_symbols | set_sheet_show_outline_symbols(sheet: int, show: bool) -> None | Set the sheet's showOutlineSymbols flag. |
set_sheet_right_to_left | set_sheet_right_to_left(sheet: int, right_to_left: bool) -> None | Set the sheet's rightToLeft flag. |
set_sheet_tab_selected | set_sheet_tab_selected(sheet: int, selected: bool) -> None | Set the sheet's tabSelected flag. |
set_sheet_top_left | set_sheet_top_left(sheet: int, row: int, col: int) -> None | Set the sheet view's scroll origin (topLeftCell). |
set_sheet_pane_top_left | set_sheet_pane_top_left(sheet: int, row: int, col: int) -> None | Set the first visible cell of a frozen or split view's lower-right pane. |
set_sheet_split | set_sheet_split(sheet: int, x_twips: float, y_twips: float) -> None | Split the view at x_twips / y_twips (0 for none on that axis). |
get_sheet_selection | get_sheet_selection(sheet: int) -> Tuple[Tuple[int, int], List[MergeRange]] | Return ((active_row, active_col), ranges) of the active pane's selection. |
set_sheet_selection | set_sheet_selection(sheet: int, active_row: int, active_col: int, ranges: Sequence[MergeRange] = ...) -> None | Replace the active pane's selection; no ranges selects the active cell alone. |
set_sheet_view_mode | set_sheet_view_mode(sheet: int, mode: str) -> None | Set the sheet's <sheetView view="..."> mode: "", |
Rows, columns and geometry
| Name | Signature | Description |
|---|---|---|
get_sheet_columns | get_sheet_columns(sheet: int) -> List[ColumnLayout] | Return the column-layout overrides on sheet. |
set_column_width | set_column_width(sheet: int, first: int, last: int, width: float) -> None | Set the column width override on [first, last]. |
set_column_hidden | set_column_hidden(sheet: int, first: int, last: int, hidden: bool) -> None | Set the column hidden flag on [first, last]. |
set_column_outline | set_column_outline(sheet: int, first: int, last: int, level: int) -> None | Set the column outline level (0-7) on [first, last]. |
set_column_collapsed | set_column_collapsed(sheet: int, first: int, last: int, collapsed: bool) -> None | Set or clear the collapsed flag on the columns [first, last]. |
get_sheet_row_overrides | get_sheet_row_overrides(sheet: int) -> List[RowLayout] | Return the row-layout overrides on sheet. |
set_row_height | set_row_height(sheet: int, row: int, height: float) -> None | Set the row height override at row. |
clear_row_height | clear_row_height(sheet: int, row: int) -> None | Remove the height override at row (back to the sheet default). |
set_column_style | set_column_style(sheet: int, first: int, last: int, xf_index: int) -> None | Set the cell-style XF on [first, last], keeping the other column attributes. |
clear_column_style | clear_column_style(sheet: int, first: int, last: int) -> None | Remove the cell-style XF on [first, last], keeping the other column attributes. |
set_row_style | set_row_style(sheet: int, first: int, last: int, xf_index: int) -> None | Set the cell-style XF on the inclusive row span first..last, keeping the other row attributes. |
clear_row_style | clear_row_style(sheet: int, first: int, last: int) -> None | Remove the cell-style XF on the inclusive row span first..last, keeping the other row attributes. |
clear_column_width | clear_column_width(sheet: int, first: int, last: int) -> None | Remove the width override on [first, last] (back to the sheet default). |
get_sheet_format_defaults | get_sheet_format_defaults(sheet: int) -> SheetFormatDefaults | Read the sheet's default column / row metrics (<sheetFormatPr>). |
set_sheet_format_defaults | set_sheet_format_defaults(sheet: int, defaults: SheetFormatDefaults) -> None | Replace the sheet's default column / row metrics; a None flag keeps the stored one. |
get_cell_rect_pt | get_cell_rect_pt(sheet: int, cell_range: MergeRange, mode: Union[GeometryMode, int] = ...) -> RectPt | Return the rectangle covering cell_range in points from the top-left of A1. |
get_column_width_pt | get_column_width_pt(sheet: int, col: int, mode: Union[GeometryMode, int] = ...) -> float | Return the effective width of col in points (0 when hidden). |
get_row_height_pt | get_row_height_pt(sheet: int, row: int) -> float | Return the effective height of row in points (0 when hidden). |
get_width_model | get_width_model(sheet: int, mode: Union[GeometryMode, int] = ...) -> WidthModel | Return the character-unit to point conversion model in mode. |
column_chars_to_pt | column_chars_to_pt(sheet: int, chars: float, mode: Union[GeometryMode, int] = ...) -> float | Convert a stored column width (padding included) to points, snapped to whole screen pixels. |
column_pt_to_chars | column_pt_to_chars(sheet: int, pt: float, mode: Union[GeometryMode, int] = ...) -> float | Convert points to the stored column width Excel writes for that column. |
set_row_hidden | set_row_hidden(sheet: int, row: int, hidden: bool) -> None | Set the row hidden flag at row. |
set_row_outline | set_row_outline(sheet: int, row: int, level: int) -> None | Set the row outline level (0-7) at row. |
set_row_collapsed | set_row_collapsed(sheet: int, row: int, collapsed: bool) -> None | Set or clear the collapsed flag at row. |
Display text
| Name | Signature | Description |
|---|---|---|
get_display_text | get_display_text(sheet: int, row: int, col: int) -> Tuple[str, DisplayStatus] | Return the text Excel displays for the cell and the rendering outcome. |
format_value | format_value(value: Value, format_code: str = ...) -> Tuple[str, DisplayStatus] | Render value under the number format format_code (empty means General). |
Styles
| Name | Signature | Description |
|---|---|---|
range_style_bases | range_style_bases(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int) -> List[int] | List, ascending, every cell XF some cell of the selection resolves to. |
remap_range_style | remap_range_style(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int, mapping: Dict[int, int]) -> None | Remap the XFs of a selection: a cell resolving to key k ends at mapping[k]. |
snapshot_range_style | snapshot_range_style(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int) -> bytes | Capture the style state of a selection as opaque bytes for restore_range_style. |
restore_range_style | restore_range_style(sheet: int, data: Union[bytes, bytearray, memoryview]) -> None | Put a snapshot_range_style capture back on sheet. |
get_cell_xf_index | get_cell_xf_index(sheet: int, row: int, col: int) -> int | Return the xf (style record) index attached to a cell. |
set_cell_xf_index | set_cell_xf_index(sheet: int, row: int, col: int, xf_index: int) -> None | Store xf_index on the cell at (row, col). |
clear_cell_xf_index | clear_cell_xf_index(sheet: int, row: int, col: int) -> None | Remove the direct style assignment from the cell at (row, col). |
set_range_xf_index | set_range_xf_index(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int, xf_index: int) -> None | Store xf_index on every cell in the inclusive rectangle. |
get_cell_xf | get_cell_xf(xf_index: int) -> CellXf | Return the resolved <xf> record at xf_index. |
get_font | get_font(font_index: int) -> FontRecord | Return the font record at font_index. |
get_fill | get_fill(fill_index: int) -> FillRecord | Return the fill record at fill_index. |
get_border | get_border(border_index: int) -> Dict[str, object] | Return the border record at border_index. |
get_dxf | get_dxf(dxf_index: int) -> DifferentialFormat | Read one differential format by its conditional-format dxfId. |
get_num_fmt | get_num_fmt(num_fmt_id: int) -> str | Return the format code registered for num_fmt_id. |
font_count | font_count() -> int | Return the number of font records registered. |
fill_count | fill_count() -> int | Return the number of fill records registered. |
border_count | border_count() -> int | Return the number of border records registered. |
cell_xf_count | cell_xf_count() -> int | Return the number of <xf> records registered. |
cell_style_count | cell_style_count() -> int | Return the number of named cell styles. |
cell_style_xf_count | cell_style_xf_count() -> int | Return the number of <cellStyleXfs> records. |
dxf_count | dxf_count() -> int | Return the number of differential formats available to CF rules. |
add_font | add_font(record: FontRecord) -> int | Add (dedup) a font record; return its index. |
set_font | set_font(font_index: int, record: FontRecord) -> None | Overwrite an existing font slot in place. |
set_default_font | set_default_font(record: FontRecord) -> None | Declare the workbook's default font (font 0). |
add_fill | add_fill(record: FillRecord) -> int | Add (dedup) a fill record; return its index. |
add_border | add_border(sides: Dict[str, object]) -> int | Add (dedup) a border record; return its index. |
add_num_fmt | add_num_fmt(format_code: str) -> int | Add (dedup) a number-format code; return its resolved id. |
add_cell_xf | add_cell_xf(record: CellXf) -> int | Add (dedup) an <xf> record; return its index. |
add_cell_style_xf | add_cell_style_xf(record: CellXf) -> int | Add (dedup) a named-style <xf>; return its <cellStyleXfs> id. |
add_batch | add_batch(*, fonts: Optional[Sequence[FontRecord]] = ..., fills: Optional[Sequence[FillRecord]] = ..., borders: Optional[Sequence[Dict[str, object]]] = ..., num_fmts: Optional[Sequence[str]] = ..., cell_xfs: Optional[Sequence[CellXf]] = ...) -> StyleBatchIndices | Add (dedup) whole style tables in one call. |
add_dxf | add_dxf(record: DifferentialFormat) -> int | Add (dedup) a differential format and return its dxfId. |
set_cell_style | set_cell_style(record: CellStyle) -> None | Add or replace the named <cellStyle> record record.name. |
remove_cell_style | remove_cell_style(name: str) -> None | Remove the named cell style name. |
get_effective_style | get_effective_style(sheet: int, row: int, col: int) -> EffectiveStyle | Read the effective style of the cell at (row, col); the cell need not exist. |
get_cell_style | get_cell_style(index: int) -> CellStyle | Return the named cell style at index. |
get_cell_style_xf | get_cell_style_xf(index: int) -> CellXf | Return the named-style xf record at index. |
Themes and colors
| Name | Signature | Description |
|---|---|---|
get_theme | get_theme() -> Theme | Read the theme's 12 scheme colours and typefaces. |
set_theme_colors | set_theme_colors(colors: Sequence[int]) -> None | Replace the theme's 12 scheme colours (a:clrScheme order; alpha ignored). |
set_theme_fonts | set_theme_fonts(fonts: ThemeFonts) -> None | Replace the theme's major and minor typefaces. |
set_theme_script_font | set_theme_script_font(major: bool, script: str, typeface: str) -> None | Set the typeface of one script in the major (heading) or minor (body) font set. |
reset_theme | reset_theme() -> None | Remove the theme part so the workbook reports the default theme. |
resolve_color | resolve_color(spec: ColorSpec, context: Union[ColorContext, int] = ...) -> ResolvedColor | Resolve spec to the 0xAARRGGBB Excel renders. |
Merges
| Name | Signature | Description |
|---|---|---|
add_merge | add_merge(sheet: int, merge: MergeRange) -> None | Append a merge range to sheet. |
remove_merge | remove_merge(sheet: int, merge: MergeRange) -> None | Remove every merge on sheet overlapping merge. |
remove_merge_at | remove_merge_at(sheet: int, index: int) -> None | Remove the merge at index on sheet. |
clear_merges | clear_merges(sheet: int) -> None | Drop every merge range on sheet. |
merge_count | merge_count(sheet: int) -> int | Return the number of merge ranges on sheet. |
get_merges | get_merges(sheet: int) -> List[MergeRange] | Return every merge range on sheet. |
get_merges_in_range | get_merges_in_range(sheet: int, cell_range: MergeRange) -> List[MergeRange] | Return every merge range on sheet that intersects cell_range. |
Comments and hyperlinks
| Name | Signature | Description |
|---|---|---|
add_hyperlink | add_hyperlink(sheet: int, row: int, col: int, target: str, display: str = ..., tooltip: str = ..., location: str = ...) -> None | Append a hyperlink to sheet. |
add_hyperlink_range | add_hyperlink_range(sheet: int, row: int, col: int, last_row: int, last_col: int, target: str, display: str = ..., tooltip: str = ..., location: str = ...) -> None | Append a hyperlink covering the inclusive cell rectangle. |
remove_hyperlink | remove_hyperlink(sheet: int, row: int, col: int) -> None | Remove every hyperlink anchored at (row, col) on sheet. |
remove_hyperlink_at | remove_hyperlink_at(sheet: int, index: int) -> None | Remove the hyperlink at index on sheet. |
clear_hyperlinks | clear_hyperlinks(sheet: int) -> None | Drop every hyperlink on sheet. |
hyperlink_count | hyperlink_count(sheet: int) -> int | Return the number of hyperlinks on sheet. |
get_hyperlinks | get_hyperlinks(sheet: int) -> List[Hyperlink] | Return every hyperlink on sheet. |
get_comment | get_comment(sheet: int, row: int, col: int) -> Optional[Comment] | Return the comment at (sheet, row, col) or None if absent. |
set_comment | set_comment(sheet: int, row: int, col: int, author: str, text: str) -> None | Set, replace, or (empty text) remove a cell comment. |
get_comment_visible | get_comment_visible(sheet: int, row: int, col: int) -> Optional[bool] | Return whether the note at the cell is shown without hovering, or None if absent. |
set_comment_visible | set_comment_visible(sheet: int, row: int, col: int, visible: bool) -> None | Show or hide the note at the cell; its box geometry is kept. |
comment_count | comment_count(sheet: int) -> int | Return the number of comments on sheet. |
get_comments | get_comments(sheet: int) -> List[CommentEntry] | Return every comment on sheet in storage order. |
Threaded comments and persons
| Name | Signature | Description |
|---|---|---|
get_threaded_comments | get_threaded_comments(sheet: int) -> List[ThreadedComment] | Return the sheet's threaded comments in file order (openers followed by their replies). |
add_threaded_comment | add_threaded_comment(sheet: int, comment: ThreadedComment) -> None | Add a threaded comment: a new thread when parent_id is empty, else a reply. |
edit_threaded_comment | edit_threaded_comment(sheet: int, comment_id: str, text: str, mentions: Sequence[Mention] = ...) -> None | Replace the text and mentions of the comment comment_id. |
set_thread_resolved | set_thread_resolved(sheet: int, thread_id: str, done: bool) -> None | Set the resolved state of the thread opened by thread_id. |
remove_threaded_comment | remove_threaded_comment(sheet: int, comment_id: str) -> None | Remove the comment comment_id; removing a thread opener removes its whole thread. |
get_persons | get_persons() -> List[Person] | Return the workbook's person list in file order. |
add_person | add_person(person: Person) -> None | Append a person to the workbook's person list. |
remove_person | remove_person(person_id: str) -> None | Remove the person person_id (refused while a comment or mention still names them). |
AutoFilter
| Name | Signature | Description |
|---|---|---|
get_auto_filter_xml | get_auto_filter_xml(sheet: int) -> str | Return the sheet's <autoFilter> XML fragment, or "". |
set_auto_filter_xml | set_auto_filter_xml(sheet: int, xml: str) -> None | Replace the sheet's <autoFilter> XML fragment. |
get_auto_filter | get_auto_filter(sheet: int) -> Optional[AutoFilter] | Return the sheet AutoFilter, or None when the sheet has none. |
set_auto_filter | set_auto_filter(sheet: int, auto_filter: AutoFilter) -> None | Replace the sheet AutoFilter. |
remove_auto_filter | remove_auto_filter(sheet: int) -> None | Remove the sheet AutoFilter (no-op when absent). |
apply_auto_filter | apply_auto_filter(sheet: int) -> None | Hide the body rows the sheet AutoFilter excludes and show the rest. |
clear_auto_filter | clear_auto_filter(sheet: int) -> None | Drop every column criterion of the sheet AutoFilter and show all its body rows. |
evaluate_auto_filter | evaluate_auto_filter(sheet: int) -> Tuple[int, List[bool]] | Evaluate the sheet AutoFilter without changing the sheet. |
get_table_auto_filter | get_table_auto_filter(table_index: int) -> Optional[AutoFilter] | Return the AutoFilter of table table_index, or None when it has none. |
set_table_auto_filter | set_table_auto_filter(table_index: int, auto_filter: AutoFilter) -> None | Replace the AutoFilter of table table_index. |
remove_table_auto_filter | remove_table_auto_filter(table_index: int) -> None | Remove the AutoFilter of table table_index (no-op when absent). |
apply_table_auto_filter | apply_table_auto_filter(table_index: int) -> None | Hide the body rows the table AutoFilter excludes and show the rest. |
clear_table_auto_filter | clear_table_auto_filter(table_index: int) -> None | Drop every column criterion of the table AutoFilter and show all its body rows. |
evaluate_table_auto_filter | evaluate_table_auto_filter(table_index: int) -> Tuple[int, List[bool]] | Evaluate the table AutoFilter; returns (first_row, match) as evaluate_auto_filter. |
Data validation
| Name | Signature | Description |
|---|---|---|
validation_count | validation_count(sheet: int) -> int | Return the number of data-validation rules on sheet. |
get_validation_at | get_validation_at(sheet: int, index: int) -> DataValidation | Read the index-th data-validation rule on sheet. |
get_validations | get_validations(sheet: int) -> List[DataValidation] | Return every data-validation rule on sheet. |
add_validation | add_validation(sheet: int, validation: DataValidationInput) -> None | Append a data-validation rule to sheet. |
remove_validation_at | remove_validation_at(sheet: int, index: int) -> None | Remove the validation rule at index on sheet. |
clear_validations | clear_validations(sheet: int) -> None | Drop every validation rule on sheet. |
validate_value | validate_value(sheet: int, row: int, col: int, value: Value) -> ValidationOutcome | Check value against the data-validation rule covering (row, col) without storing it. |
list_invalid_cells | list_invalid_cells(sheet: int, cursor: Optional[int] = ..., limit: Optional[int] = ...) -> Tuple[List[Cell], Optional[int]] | Return one page of the populated cells failing their data-validation rule (row-major). |
Conditional formats
| Name | Signature | Description |
|---|---|---|
evaluate_cf_range | evaluate_cf_range(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int, today_serial: float = ...) -> List[CfCellResult] | Evaluate every CF block on sheet against an inclusive range. |
cf_count | cf_count(sheet: int) -> int | Return the number of CF rules on sheet (flattened). |
get_conditional_format_at | get_conditional_format_at(sheet: int, index: int) -> ConditionalFormat | Read the index-th CF rule on sheet (flattened order). |
get_conditional_formats | get_conditional_formats(sheet: int) -> List[ConditionalFormat] | Return every CF rule on sheet in flattened priority order. |
add_conditional_format | add_conditional_format(sheet: int, rule: ConditionalFormatInput) -> int | Append a CF rule to sheet; return its index. |
remove_conditional_format_at | remove_conditional_format_at(sheet: int, index: int) -> None | Remove the CF rule at index on sheet (flattened order). |
clear_conditional_formats | clear_conditional_formats(sheet: int) -> None | Drop every CF block on sheet. |
Images and drawings
| Name | Signature | Description |
|---|---|---|
probe_image | probe_image(data: Union[bytes, bytearray, memoryview]) -> ImageInfo | Sniff the format and pixel size of PNG, JPEG, GIF or BMP bytes without touching the workbook. |
list_drawing_objects | list_drawing_objects(sheet: int) -> List[DrawingObject] | Return the anchored objects of the sheet's drawing in document order. |
get_image | get_image(sheet: int, object_id: int) -> bytes | Return the bytes of the picture object_id (copied out of WASM memory). |
insert_image | insert_image(sheet: int, data: Union[bytes, bytearray, memoryview], *, name: str = ..., descr: str = ..., anchor_kind: Union[AnchorKind, int] = ..., edit_as: Union[AnchorEditAs, int] = ..., row: int = ..., col: int = ..., row_off_emu: int = ..., col_off_emu: int = ..., width_emu: int = ..., height_emu: int = ...) -> int | Insert an image anchored at (row, col) and return its object id. |
remove_drawing | remove_drawing(sheet: int, object_id: int) -> None | Remove the picture or chart object_id and the parts only it reaches; other drawing content is kept. |
set_drawing_anchor | set_drawing_anchor(sheet: int, object_id: int, *, anchor_kind: Union[AnchorKind, int] = ..., edit_as: Union[AnchorEditAs, int] = ..., row: int = ..., col: int = ..., row_off_emu: int = ..., col_off_emu: int = ..., width_emu: int = ..., height_emu: int = ...) -> None | Move and resize the picture or chart object_id, keeping its id and every other element. |
set_drawing_z_order | set_drawing_z_order(sheet: int, object_id: int, index: int) -> None | Make the picture or chart object_id item index of list_drawing_objects (0 is the back). |
snapshot_drawing | snapshot_drawing(sheet: int, object_id: int) -> bytes | Capture the picture or chart object_id as opaque bytes for restore_drawing. |
restore_drawing | restore_drawing(sheet: int, data: Union[bytes, bytearray, memoryview], *, new_id: bool = ...) -> int | Put a snapshot_drawing capture back and return the object's id. |
list_shapes | list_shapes(sheet: int) -> List[Shape] | Return the shapes, connectors and groups of the sheet's drawing in z-order (back first). |
insert_shape | insert_shape(sheet: int, *, anchor_kind: Union[AnchorKind, int], edit_as: Union[AnchorEditAs, int] = ..., from_row: int = ..., from_col: int = ..., from_row_off: int = ..., from_col_off: int = ..., to_row: int = ..., to_col: int = ..., to_row_off: int = ..., to_col_off: int = ..., cx: int = ..., cy: int = ..., name: Optional[str] = ..., prst: Optional[str] = ..., text: Optional[str] = ..., text_box: Optional[bool] = ..., fill_kind: Optional[Union[ShapePaint, int]] = ..., fill_rgb: int = ..., line_kind: Optional[Union[ShapePaint, int]] = ..., line_rgb: int = ..., line_width_emu: Optional[int] = ..., rotation: Optional[int] = ..., hidden: Optional[bool] = ...) -> int | Append a shape on top of the sheet's drawing and return its object id. |
update_shape | update_shape(sheet: int, object_id: int, *, anchor_kind: Optional[Union[AnchorKind, int]] = ..., edit_as: Union[AnchorEditAs, int] = ..., from_row: int = ..., from_col: int = ..., from_row_off: int = ..., from_col_off: int = ..., to_row: int = ..., to_col: int = ..., to_row_off: int = ..., to_col_off: int = ..., cx: int = ..., cy: int = ..., name: Optional[str] = ..., prst: Optional[str] = ..., text: Optional[str] = ..., text_box: Optional[bool] = ..., fill_kind: Optional[Union[ShapePaint, int]] = ..., fill_rgb: int = ..., line_kind: Optional[Union[ShapePaint, int]] = ..., line_rgb: int = ..., line_width_emu: Optional[int] = ..., rotation: Optional[int] = ..., hidden: Optional[bool] = ...) -> None | Apply the arguments that are not None to the shape object_id; the rest of its XML is kept. |
remove_shape | remove_shape(sheet: int, object_id: int) -> None | Remove the shape, connector or group object_id with its children. |
list_slicers | list_slicers(sheet: int) -> List[Slicer] | Return the table slicers hosted by the sheet; slicers over a pivot cache are not listed. |
add_slicer | add_slicer(sheet: int, table: int, column: int, *, anchor: Sequence[int], name: Optional[str] = ..., caption: Optional[str] = ..., style: Optional[str] = ..., column_count: Optional[int] = ..., row_height: Optional[int] = ..., sort_order: Optional[Union[SlicerSortOrder, int]] = ..., cross_filter: Optional[Union[SlicerCrossFilter, int]] = ...) -> int | Add a slicer over column column of table table and return its frame's object id. |
update_slicer | update_slicer(sheet: int, index: int, *, anchor: Optional[Sequence[int]] = ..., caption: Optional[str] = ..., style: Optional[str] = ..., column_count: Optional[int] = ..., row_height: Optional[int] = ..., sort_order: Optional[Union[SlicerSortOrder, int]] = ..., cross_filter: Optional[Union[SlicerCrossFilter, int]] = ...) -> None | Apply the arguments that are not None to slicer index; the rest of its XML is kept. |
remove_slicer | remove_slicer(sheet: int, index: int) -> None | Remove slicer index with its drawing frame, and its cache when no other slicer uses it. |
list_sparkline_groups | list_sparkline_groups(sheet: int) -> List[SparklineGroup] | Return the sheet's sparkline groups in document order, each with its sparklines. |
add_sparkline_group | add_sparkline_group(sheet: int, group: SparklineGroup) -> None | Append group with its sparklines (at least one) to the sheet's worksheet extension list. |
update_sparkline_group | update_sparkline_group(sheet: int, index: int, group: SparklineGroup) -> None | Rewrite the modelled attributes, colours and date range of group index from group. |
set_sparkline_group_sparklines | set_sparkline_group_sparklines(sheet: int, index: int, sparklines: Sequence[Sparkline]) -> None | Replace the sparklines of group index with sparklines (at least one). |
remove_sparkline_group | remove_sparkline_group(sheet: int, index: int) -> None | Remove sparkline group index. |
Charts
| Name | Signature | Description |
|---|---|---|
get_chart | get_chart(sheet: int, object_id: int) -> ChartInfo | Return the typed view of the chart object_id: plots, series, axes, legend and source. |
get_chart_data | get_chart_data(sheet: int, object_id: int) -> ChartData | Resolve the chart's series against the current cell values by Excel's rules. |
preview_chart_data | preview_chart_data(sheet: int, object_id: int, overrides: Optional[ChartPreviewOverrides] = ...) -> ChartData | Resolve the data of a copy of the chart with overrides applied; the workbook is unchanged. |
insert_chart | insert_chart(sheet: int, kind: Union[ChartInsertKind, int], source: str, *, grouping: Union[ChartGrouping, int] = ..., direction: Union[ChartSeriesDirection, int] = ..., header_row: Optional[bool] = ..., header_column: Optional[bool] = ..., title: Optional[str] = ..., legend: Union[ChartLegendPosition, int] = ..., name: str = ..., description: str = ..., anchor_kind: Union[AnchorKind, int] = ..., edit_as: Union[AnchorEditAs, int] = ..., row: int = ..., col: int = ..., row_off_emu: int = ..., col_off_emu: int = ..., width_emu: int = ..., height_emu: int = ...) -> int | Create a chart over the A1 rectangle source and return its object id. |
set_chart_type | set_chart_type(sheet: int, object_id: int, plot: int, kind: Union[ChartInsertKind, int], grouping: Union[ChartGrouping, int] = ...) -> None | Replace plot group plot with kind, keeping each series' references, idx, order and explicit colors. |
set_chart_title | set_chart_title(sheet: int, object_id: int, title: Union[str, None, ChartTitleInfo]) -> None | Set the chart title to title; None removes it. |
set_chart_legend | set_chart_legend(sheet: int, object_id: int, position: Union[ChartLegendPosition, int], overlay: bool = ..., *, hidden_series: Optional[Sequence[int]] = ...) -> None | Set the legend position (NONE removes it) and overlay. |
set_chart_axis | set_chart_axis(sheet: int, object_id: int, axis_id: int, patch: ChartAxisPatch) -> None | Patch axis axis_id: an omitted key is kept, None removes the element. |
set_chart_display | set_chart_display(sheet: int, object_id: int, blanks_as: Union[ChartBlanksAs, int], plot_visible_only: Optional[bool]) -> None | Write how blanks plot and whether hidden cells are skipped; ABSENT / None remove the element. |
set_chart_series | set_chart_series(sheet: int, object_id: int, plot: int, series_idx: int, patch: ChartSeriesPatch) -> None | Patch the series with c:idx series_idx of plot group plot; a changed reference refreshes its cache. |
set_chart_point | set_chart_point(sheet: int, object_id: int, plot: int, series_idx: int, point_idx: int, patch: Optional[ChartPointPatch]) -> None | Patch point point_idx of a series; None (or an empty patch) removes the point's formatting. |
set_chart_plot | set_chart_plot(sheet: int, object_id: int, plot: int, patch: ChartPlotPatch) -> None | Patch plot group plot; a field the plot type does not have is rejected. |
set_chart_filter | set_chart_filter(sheet: int, object_id: int, hidden_series: Sequence[int], hidden_categories: Sequence[int]) -> None | Replace the chart filter: the listed series (by c:idx) and category positions are hidden. |
add_chart_series | add_chart_series(sheet: int, object_id: int, plot: int, patch: ChartSeriesPatch) -> int | Append a series to plot group plot and return its c:idx. |
remove_chart_series | remove_chart_series(sheet: int, object_id: int, plot: int, series_idx: int) -> None | Remove the series with c:idx series_idx from plot group plot. |
set_chart_source | set_chart_source(sheet: int, object_id: int, source: str, direction: Union[ChartSeriesDirection, int] = ..., header_row: Optional[bool] = ..., header_column: Optional[bool] = ...) -> None | Rebuild every series from source by the insert splitting rules. |
Print settings and pagination
| Name | Signature | Description |
|---|---|---|
paginate | paginate(sheet: int) -> PaginationResult | Resolve the worksheet's print area, page breaks, and page count. |
get_page_setup_xml | get_page_setup_xml(sheet: int) -> str | Return the sheet's <pageSetup> fragment, or "". |
set_page_setup_xml | set_page_setup_xml(sheet: int, xml: str) -> None | Replace the sheet's <pageSetup> fragment. |
get_page_margins_xml | get_page_margins_xml(sheet: int) -> str | Return the sheet's <pageMargins> fragment, or "". |
set_page_margins_xml | set_page_margins_xml(sheet: int, xml: str) -> None | Replace the sheet's <pageMargins> fragment. |
get_print_options_xml | get_print_options_xml(sheet: int) -> str | Return the sheet's <printOptions> fragment, or "". |
set_print_options_xml | set_print_options_xml(sheet: int, xml: str) -> None | Replace the sheet's <printOptions> fragment. |
get_header_footer_xml | get_header_footer_xml(sheet: int) -> str | Return the sheet's <headerFooter> fragment, or "". |
set_header_footer_xml | set_header_footer_xml(sheet: int, xml: str) -> None | Replace the sheet's <headerFooter> fragment. |
get_sheet_pr_xml | get_sheet_pr_xml(sheet: int) -> str | Return the sheet's <sheetPr> fragment, or "". |
set_sheet_pr_xml | set_sheet_pr_xml(sheet: int, xml: str) -> None | Replace the sheet's <sheetPr> fragment. |
set_fit_to_page | set_fit_to_page(sheet: int, enabled: bool) -> None | Set or clear <sheetPr><pageSetUpPr fitToPage>. |
get_print_area | get_print_area(sheet: int) -> str | Return the print area as comma-separated A1 ranges, or "". |
set_print_area | set_print_area(sheet: int, ranges_a1: str) -> None | Write _xlnm.Print_Area from one or more A1 ranges. |
get_print_titles | get_print_titles(sheet: int) -> tuple[str, str] | Return (repeat_rows, repeat_cols) as "1:2" / "A:A". |
set_print_titles | set_print_titles(sheet: int, repeat_rows: str = ..., repeat_cols: str = ...) -> None | Write _xlnm.Print_Titles from a row span and a column span. |
add_row_break | add_row_break(sheet: int, row: int, manual: bool = ...) -> None | Upsert a row break before row, spanning the whole sheet. |
add_col_break | add_col_break(sheet: int, col: int, manual: bool = ...) -> None | Upsert a column break before col, spanning the whole sheet. |
remove_row_break | remove_row_break(sheet: int, row: int) -> None | Remove the row break at row. |
remove_col_break | remove_col_break(sheet: int, col: int) -> None | Remove the column break at col. |
clear_breaks | clear_breaks(sheet: int) -> None | Remove every manual break on both axes. |
get_row_breaks | get_row_breaks(sheet: int) -> List[PageBreak] | Return the row breaks, ascending by row. |
get_col_breaks | get_col_breaks(sheet: int) -> List[PageBreak] | Return the column breaks, ascending by column. |
set_page_setup | set_page_setup(sheet: int, *, orientation: Optional[int] = ..., paper_size: Optional[int] = ..., scale: Optional[int] = ..., fit_to_width: Optional[int] = ..., fit_to_height: Optional[int] = ..., fit_to_page: Optional[bool] = ...) -> None | Apply a partial <pageSetup> update. |
set_page_margins | set_page_margins(sheet: int, *, left: Optional[float] = ..., right: Optional[float] = ..., top: Optional[float] = ..., bottom: Optional[float] = ..., header: Optional[float] = ..., footer: Optional[float] = ...) -> None | Apply a partial <pageMargins> update, in inches. |
set_print_options | set_print_options(sheet: int, *, grid_lines: Optional[bool] = ..., headings: Optional[bool] = ..., horizontal_centered: Optional[bool] = ..., vertical_centered: Optional[bool] = ...) -> None | Apply a partial <printOptions> update. |
set_header_footer | set_header_footer(sheet: int, *, odd_header: Optional[str] = ..., odd_footer: Optional[str] = ..., even_header: Optional[str] = ..., even_footer: Optional[str] = ..., first_header: Optional[str] = ..., first_footer: Optional[str] = ..., different_odd_even: Optional[bool] = ..., different_first: Optional[bool] = ..., scale_with_doc: Optional[bool] = ..., align_with_margins: Optional[bool] = ...) -> None | Apply a partial <headerFooter> update. |
get_page_setup | get_page_setup(sheet: int) -> PageSetup | Read the effective page setup and which attributes state it. |
get_page_margins | get_page_margins(sheet: int) -> PageMargins | Read the effective page margins in inches, with presence flags. |
PivotTables
| Name | Signature | Description |
|---|---|---|
pivot_count | pivot_count(sheet: int) -> int | Return the number of PivotTables anchored on sheet. |
pivot_layout | pivot_layout(sheet: int, pivot_index: int) -> PivotLayout | Evaluate and project a PivotTable into concrete grid cells. |
get_pivot_report_layout | get_pivot_report_layout(sheet: int, pivot_index: int) -> PivotReportLayout | Return the pivot's compact, tabular, or outline report layout. |
set_pivot_report_layout | set_pivot_report_layout(sheet: int, pivot_index: int, layout: Union[PivotReportLayout, int]) -> None | Set the pivot's compact, tabular, or outline report layout. |
pivot_create | pivot_create(sheet: int, name: str, cache_id: int, anchor_row: int, anchor_col: int) -> int | Create a new empty pivot table; return its flat index. |
pivot_remove | pivot_remove(sheet: int, pivot_index: int) -> None | Remove the pivot table at pivot_index. |
pivot_set_name | pivot_set_name(sheet: int, pivot_index: int, name: str) -> None | Rename the pivot table. |
pivot_set_anchor | pivot_set_anchor(sheet: int, pivot_index: int, anchor_row: int, anchor_col: int, span_rows: int, span_cols: int) -> None | Update the pivot's anchor cell and span. |
pivot_set_grand_totals | pivot_set_grand_totals(sheet: int, pivot_index: int, rows_enabled: bool, cols_enabled: bool) -> None | Toggle the row / column grand-total bands. |
pivot_set_style_info | pivot_set_style_info(sheet: int, pivot_index: int, name: Optional[str] = None, *, show_row_headers: bool = False, show_col_headers: bool = False, show_row_stripes: bool = False, show_col_stripes: bool = False, show_last_column: bool = False) -> None | Set the pivot's table style and toggles, making the style element present. |
pivot_name | pivot_name(sheet: int, pivot_index: int) -> str | Return the pivot's name. |
pivot_grand_totals | pivot_grand_totals(sheet: int, pivot_index: int) -> Tuple[bool, bool] | Return (rows, cols), the flags pivot_set_grand_totals writes. |
pivot_style_info | pivot_style_info(sheet: int, pivot_index: int) -> PivotStyleInfo | Return the table style pivot_set_style_info writes. |
pivot_row_field_order | pivot_row_field_order(sheet: int, pivot_index: int) -> List[int] | Return the row-axis field order (the list pivot_set_row_field_order takes). |
pivot_col_field_order | pivot_col_field_order(sheet: int, pivot_index: int) -> List[int] | Return the column-axis field order. |
pivot_field_at | pivot_field_at(sheet: int, pivot_index: int, field_idx: int) -> PivotFieldInfo | Read the definition of pivot field field_idx. |
pivot_field_item_count | pivot_field_item_count(sheet: int, pivot_index: int, field_idx: int) -> int | Return the number of items in pivot field field_idx's item list. |
pivot_field_item_at | pivot_field_item_at(sheet: int, pivot_index: int, field_idx: int, item_idx: int) -> PivotItemInfo | Read item item_idx of pivot field field_idx. |
pivot_data_field_at | pivot_data_field_at(sheet: int, pivot_index: int, data_field_idx: int) -> PivotDataFieldSpec | Read data field data_field_idx in the shape pivot_data_field_add accepts. |
pivot_field_count | pivot_field_count(sheet: int, pivot_index: int) -> int | Return the number of fields configured on the pivot. |
pivot_field_add | pivot_field_add(sheet: int, pivot_index: int, spec: PivotFieldSpec) -> int | Place a field on the pivot; return its index. |
pivot_field_clear | pivot_field_clear(sheet: int, pivot_index: int) -> None | Drop every field from the pivot. |
pivot_field_set_axis | pivot_field_set_axis(sheet: int, pivot_index: int, field_idx: int, axis: Union[PivotAxis, int]) -> None | Set the axis of pivot field field_idx. |
pivot_field_set_sort | pivot_field_set_sort(sheet: int, pivot_index: int, field_idx: int, order: Union[PivotSortOrder, int], by_field: str = ...) -> None | Set the sibling order of pivot field field_idx. |
pivot_field_set_subtotal_top | pivot_field_set_subtotal_top(sheet: int, pivot_index: int, field_idx: int, top: bool) -> None | Set the subtotal_top flag on pivot field field_idx. |
pivot_field_add_item | pivot_field_add_item(sheet: int, pivot_index: int, field_idx: int, name: str, visible: bool) -> None | Append a manual-filter item addressed by its label. |
pivot_field_add_item_at | pivot_field_add_item_at(sheet: int, pivot_index: int, field_idx: int, cache_index: int, visible: bool) -> None | Append a manual-filter item addressed by its cache shared-item index. |
pivot_field_clear_items | pivot_field_clear_items(sheet: int, pivot_index: int, field_idx: int) -> None | Drop every manual-filter item from pivot field field_idx. |
pivot_field_set_item_visible | pivot_field_set_item_visible(sheet: int, pivot_index: int, field_idx: int, item_idx: int, visible: bool) -> None | Toggle the visibility of item item_idx on field field_idx. |
pivot_field_add_subtotal_fn | pivot_field_add_subtotal_fn(sheet: int, pivot_index: int, field_idx: int, agg: Union[PivotAggregation, int]) -> None | Append a subtotal-fn entry to pivot field field_idx. |
pivot_field_clear_subtotal_fns | pivot_field_clear_subtotal_fns(sheet: int, pivot_index: int, field_idx: int) -> None | Drop every subtotal-fn entry from pivot field field_idx. |
pivot_field_set_date_group | pivot_field_set_date_group(sheet: int, pivot_index: int, field_idx: int, granularity: Union[PivotDateGrouping, int], calendar: Union[PivotCalendar, int], start_year: int = ..., end_year: int = ..., interval_days: int = ..., start_serial: float = ..., end_serial: float = ...) -> None | Configure date-grouping on pivot field field_idx. |
pivot_field_clear_date_group | pivot_field_clear_date_group(sheet: int, pivot_index: int, field_idx: int) -> None | Remove the date-grouping config from pivot field field_idx. |
pivot_field_set_number_format | pivot_field_set_number_format(sheet: int, pivot_index: int, field_idx: int, fmt: str) -> None | Set the numFmtId of pivot field field_idx. |
pivot_set_row_field_order | pivot_set_row_field_order(sheet: int, pivot_index: int, indices: Sequence[int]) -> None | Replace the row-axis field order with indices. |
pivot_set_col_field_order | pivot_set_col_field_order(sheet: int, pivot_index: int, indices: Sequence[int]) -> None | Replace the column-axis field order with indices. |
pivot_data_field_count | pivot_data_field_count(sheet: int, pivot_index: int) -> int | Return the number of <dataField> entries on the pivot. |
pivot_data_field_add | pivot_data_field_add(sheet: int, pivot_index: int, spec: PivotDataFieldSpec) -> int | Append a data-field entry; return its index. |
pivot_data_field_set | pivot_data_field_set(sheet: int, pivot_index: int, data_field_idx: int, spec: PivotDataFieldSpec) -> None | Replace the data-field entry at data_field_idx in place. |
pivot_data_field_clear | pivot_data_field_clear(sheet: int, pivot_index: int) -> None | Drop every data-field entry from the pivot. |
pivot_filter_count | pivot_filter_count(sheet: int, pivot_index: int) -> int | Return the number of filters on the pivot; see pivot_filter_at. |
pivot_filter_add | pivot_filter_add(sheet: int, pivot_index: int, spec: PivotFilterSpec) -> None | Append a filter to the pivot; it is saved with it. |
pivot_filter_at | pivot_filter_at(sheet: int, pivot_index: int, filter_idx: int) -> PivotFilterSpec | Read the filter at filter_idx without mutating it. |
pivot_filter_clear | pivot_filter_clear(sheet: int, pivot_index: int) -> None | Drop every listed filter from the pivot. |
pivot_filter_remove_at | pivot_filter_remove_at(sheet: int, pivot_index: int, filter_idx: int) -> None | Remove the filter at filter_idx. |
Pivot caches
| Name | Signature | Description |
|---|---|---|
pivot_cache_count | pivot_cache_count() -> int | Return the number of pivot caches owned by the workbook. |
pivot_cache_id_at | pivot_cache_id_at(index: int) -> int | Return the cache id at flat index. |
pivot_cache_create | pivot_cache_create(requested_id: int = ...) -> int | Create a new empty pivot cache; return its assigned id. |
get_pivot_cache_worksheet_source | get_pivot_cache_worksheet_source(cache_id: int) -> Optional[PivotWorksheetSource] | Return a cache's worksheet-source metadata, or None when absent. |
set_pivot_cache_worksheet_source | set_pivot_cache_worksheet_source(cache_id: int, source: Optional[PivotWorksheetSource]) -> None | Set cache worksheet-source metadata; pass None to clear it. |
pivot_cache_remove | pivot_cache_remove(cache_id: int) -> None | Remove the pivot cache with id cache_id. |
pivot_cache_field_count | pivot_cache_field_count(cache_id: int) -> int | Return the number of fields on the cache. |
pivot_cache_field_name | pivot_cache_field_name(cache_id: int, field_idx: int) -> str | Read the name of cache field field_idx. |
pivot_cache_field_add | pivot_cache_field_add(cache_id: int, name: str) -> int | Append a field to the cache; return its index. |
pivot_cache_field_clear | pivot_cache_field_clear(cache_id: int) -> None | Drop every field (and record) from the cache. |
pivot_cache_field_shared_item_count | pivot_cache_field_shared_item_count(cache_id: int, field_idx: int) -> int | Return the shared-item count on cache field field_idx. |
pivot_cache_field_add_shared_item_number | pivot_cache_field_add_shared_item_number(cache_id: int, field_idx: int, value: float) -> None | Append a numeric shared item to a cache field. |
pivot_cache_field_add_shared_item_text | pivot_cache_field_add_shared_item_text(cache_id: int, field_idx: int, value: str) -> None | Append a text shared item to a cache field. |
pivot_cache_field_add_shared_item_bool | pivot_cache_field_add_shared_item_bool(cache_id: int, field_idx: int, value: bool) -> None | Append a boolean shared item to a cache field. |
pivot_cache_field_add_shared_item_blank | pivot_cache_field_add_shared_item_blank(cache_id: int, field_idx: int) -> None | Append a blank shared item to a cache field. |
pivot_cache_field_add_shared_item_error | pivot_cache_field_add_shared_item_error(cache_id: int, field_idx: int, error_code: int) -> None | Append an Excel error shared item to a cache field. |
pivot_cache_field_clear_shared_items | pivot_cache_field_clear_shared_items(cache_id: int, field_idx: int) -> None | Drop every shared item from a cache field. |
pivot_cache_record_count | pivot_cache_record_count(cache_id: int) -> int | Return the number of records on the cache. |
pivot_cache_record_add | pivot_cache_record_add(cache_id: int) -> int | Append an empty record to the cache; return its index. |
pivot_cache_record_clear | pivot_cache_record_clear(cache_id: int) -> None | Drop every record from the cache. |
pivot_cache_record_set_number | pivot_cache_record_set_number(cache_id: int, record_idx: int, field_idx: int, value: float) -> None | Set cache cell (record_idx, field_idx) to a number. |
pivot_cache_record_set_text | pivot_cache_record_set_text(cache_id: int, record_idx: int, field_idx: int, value: str) -> None | Set cache cell (record_idx, field_idx) to text. |
pivot_cache_record_set_bool | pivot_cache_record_set_bool(cache_id: int, record_idx: int, field_idx: int, value: bool) -> None | Set cache cell (record_idx, field_idx) to a boolean. |
pivot_cache_record_set_blank | pivot_cache_record_set_blank(cache_id: int, record_idx: int, field_idx: int) -> None | Set cache cell (record_idx, field_idx) to blank. |
pivot_cache_record_set_error | pivot_cache_record_set_error(cache_id: int, record_idx: int, field_idx: int, error_code: int) -> None | Set cache cell (record_idx, field_idx) to an Excel error. |
pivot_cache_id | pivot_cache_id(sheet: int, pivot_index: int) -> int | Return the cache_id of the pivot cache the pivot draws from. |
Method notes
CellStyle is the named-style record used by set_cell_style() and get_cell_style(). Its fields are name, xf_id, builtin_id, i_level, hidden, and custom_builtin; name and xf_id are required, while the other fields use their dataclass defaults. Leave builtin_id at its default for a custom style. The xf_id points into the named-style XF table, not the per-cell XF table.
Row and column styles, clear_cell_xf_index() versus set_cell_xf_index(..., 0), and the range_style_bases() → remap_range_style() edit with its snapshot_range_style() / restore_range_style() undo capture follow Workbook operations. get_theme() returns major_scripts and minor_scripts; the script-font rules are in Presentation and geometry.
Python has no scalar evaluate_formula_text(). evaluate_formula_array(sheet, row, col, formula) returns the whole result read-only, and evaluate_cf_formula(sheet, row, col, anchor_row, anchor_col, formula) evaluates a conditional-format predicate.
get_iterative() returns IterativeSettings(enabled, max_iterations, max_change); the engine caps max_iterations at 32767 and reports the capped value. set_iterative_enabled(enabled) toggles iterative calculation while keeping the stored cap and threshold, and add_batch() registers fonts, fills, borders, number formats, and XFs in one call.
set_calc_mode(mode) takes a CalcMode; with AUTO_NO_TABLE, recalc() skips data-table results until recalc_data_tables() runs. full_precision(), calc_on_save(), ref_mode(), and date1904() read the corresponding <calcPr> and <workbookPr> settings, and each has a set_ counterpart. Other <calcPr> attributes are kept across a resave.
active_sheet() / set_active_sheet(sheet) read and write the active tab; setting it moves tabSelected and rejects a hidden sheet. Hiding or removing the active sheet activates the next visible sheet to the right, otherwise the nearest visible one on the left. set_sheet_top_left() and set_sheet_pane_top_left() set the scroll origin of the view and of the lower-right pane, and get_sheet_selection() / set_sheet_selection() address the selection of each pane. set_sheet_split(sheet, x_twips, y_twips) splits the view at a twips offset on either axis without freezing it; a split replaces a freeze and the other way round, and 0, 0 removes it. A selection in a pane the view lacks is dropped on save, and an active cell outside every selected range moves to the top-left of the first range. get_sheet_view() reports show_formulas and show_outline_symbols, which have the setters set_sheet_show_formulas() and set_sheet_show_outline_symbols().
set_row_collapsed() and set_column_collapsed() set the outline collapsed flag that the row and column override getters report. outlineLevelRow and outlineLevelCol are derived from the deepest levels on every save. An outline level above 7 raises FormulonError.
add_data_table(), get_data_table(sheet, row, col), and remove_data_table(sheet, row, col) manage What-If data tables (<f t="dataTable">). recalc() fills one-variable (column or row input) and two-variable tables by substituting each value into the input cells, recalculating the cells that read them, and restoring the inputs. Writing into a result cell raises FormulonError with kPreconditionFailed, as does a row or column insert or delete that cuts through the table or its header row and column. Result cells report =TABLE(row_input,col_input) through the formula getters, FORMULATEXT returns {=TABLE(...)}, and ISFORMULA is TRUE.
list_shapes(), insert_shape(), update_shape(), and remove_shape() cover the xdr:sp shapes and text boxes, xdr:cxnSp connectors, and xdr:grpSp groups of a sheet's drawing. An update rewrites only the fields it names and keeps the rest of the shape's XML. A shape the record cannot express is listed with ShapePaint.OTHER or empty fields and passes through a save unchanged. Shapes follow row and column edits like pictures do.
list_sparkline_groups(), add_sparkline_group(), update_sparkline_group(), set_sparkline_group_sparklines(), and remove_sparkline_group() manage the x14:sparklineGroups of a sheet. An update keeps attributes and children outside the record, such as rightToLeft, uid, and unknown extensions.
list_slicers(), add_slicer(), update_slicer(), and remove_slicer() manage table slicers. Adding one creates the slicer part, its cache, the extension entries, the defined name, and the drawing frame. Removing a slicer also removes its cache once no other slicer uses it. Removing a table or a sheet, or deleting the rows or columns under a slicer's frame, removes the slicers bound to it. Slicers over a pivot cache pass through untouched and are not listed; the selection of a table slicer lives in the table's AutoFilter.
get_workbook_protection() / set_workbook_protection() read and write <workbookProtection>, and get_protected_ranges(), add_protected_range(), update_protected_range(), and remove_protected_range() manage a sheet's <protectedRange> entries; the ranges move with row and column edits. Password hashes are stored as the host computes them, and attributes the record does not model are kept. Neither protection is enforced on cell edits.
table_rename(index, name, display_name=None) renames a table and rewrites structured references to it in cells, defined names, conditional formats, data validations, calculated-column and totals-row formulas, and chart series; a pivot cache sourced from the table follows. table_set_style_info() sets the style name and the first-column, last-column, row-stripe, and column-stripe toggles, and table_set_column_totals() sets one column's totals function, label, and formula. Turning the totals row on writes each column's totals cell. get_table_style(), set_table_style(), remove_table_style(), table_style_defaults(), and set_table_style_defaults() manage custom <tableStyles> and the default table and PivotTable style names; pivot_style_info() / pivot_set_style_info() read and write a PivotTable's style. set_defined_name_attrs(name, local_sheet_id, ...) sets a name's comment and hidden flag; replacing the name's formula keeps both.
get_comment_visible() / set_comment_visible() read and write whether a legacy note is shown. A note's box, its visibility, and the authors table of its comments part are kept across a resave, and a box follows its note through row and column edits. get_show_phonetic() / set_show_phonetic() read and write the per-cell Show Phonetic flag; saved files carry it on constants and blanks only, not on formula cells.
add_sheet() and rename_sheet() raise FormulonError with kInvalidSheetName for an empty name, a name over 31 UTF-16 units, one with : \ / ? * [ ], one that begins or ends with an apostrophe, and one that matches another sheet's name under case folding. Under the win-* profiles, the default included, History in any case is refused as well; mac-* profiles accept it. Hiding or removing the only visible sheet raises FormulonError, as does a row or column insert or delete that cuts through a data table, a legacy array block, or a PivotTable, or would push one of them or a table past the grid edge.
set_sheet_visibility() accepts SheetVisibility.VISIBLE, HIDDEN, or VERY_HIDDEN, and get_sheet_view() returns the resolved three-state value in addition to tab_hidden. set_range_xf_index() applies one style XF index over an inclusive rectangle and materializes missing cells as styled blanks.
table_create() needs column_names matching the width of ref; the caller still writes the header cells. table_update() keeps fields passed as None, and an existing table AutoFilter keeps its criteria and extensions when its range is retargeted. get_auto_filter_xml() / set_auto_filter_xml() read and write the worksheet AutoFilter as a complete opaque <autoFilter> fragment; an empty string removes it. Row and column inserts and deletes move an AutoFilter's ref and its modeled criteria and sort offsets with the cells; worksheet XML that stays opaque is preserved byte-for-byte.
add_hyperlink_range() adds one hyperlink over an inclusive rectangle; read-back Hyperlink values include last_row and last_col. A DataValidationInput with omitted allow_blank defaults to False; pass allow_blank=True to accept empty cells.
Conditional formats carry visual payloads as ColorScale, DataBar, and IconSet. DataBar exposes the x14 controls gradient, axis_position (0 automatic, 1 middle, 2 none), negative_fill, border, negative_border, axis_color, and direction (0 context, 1 left-to-right, 2 right-to-left); omitted values use the model defaults and survive save and load.
A newly created pivot cache must get a worksheet source before the workbook is saved, for example set_pivot_cache_worksheet_source(cache_id, PivotWorksheetSource(ref="A1:C10", sheet="Data")); saving a new cache without one fails. Loaded caches keep their source metadata, which may describe a non-worksheet or external source. pivot_field_add_item_at() addresses a manual-filter item by cache shared-item index, which is the only way to name the blank member; an empty label passed to pivot_field_add_item() cannot.
get_cells_in_range(sheet, cell_range, cursor=None, limit=None) returns (cells, next_cursor) in row-major order. Each Cell has row, col, formula, and value. Pass next_cursor into the next call until it is None; an omitted or zero limit uses the 65,536-cell maximum. Formula cells, non-blank values, and spill phantoms are included, while styled blanks are not. list_invalid_cells() follows the same paging contract.
Geometry methods accept GeometryMode.DISPLAY for the 96-DPI screen model or GeometryMode.PRINT for the DPI-stable pagination model. get_display_text() and format_value() return DisplayStatus.OVERFLOW with ######## when a value is outside the format's representable range, and DisplayStatus.INVALID_FORMAT when the format code is malformed; malformed formats fall back to General rendering.
probe_image() reads PNG, JPEG, GIF, or BMP dimensions without changing the workbook. list_drawing_objects() returns anchored objects in document order; get_image() copies picture bytes, insert_image() preserves existing drawing content, and remove_drawing() removes a picture or chart and releases its media when no other object references it. Threaded-comment methods include replies and person records; removing a person fails while a comment or mention still refers to that person.
AutoFilter criteria are stored separately from row visibility. Use evaluate_auto_filter() to inspect matches and apply_auto_filter() to update hidden rows; clear_auto_filter() removes criteria while retaining the AutoFilter range. Validation methods check proposed values without storing them, and list_invalid_cells() enumerates existing violations.
paginate(sheet) returns PaginationResult with page_count, print_area, horizontal_breaks, vertical_breaks, paper, margins, printable, scale, page_order, print_titles, pages, horizontal_break_manual, and vertical_break_manual. paper reports point dimensions, orientation, and whether the stored paper code was known. Each PageLayout in pages gives area_index, inclusive cell bounds, origin, and scaled size. A missing declared print area leaves print_area empty while pagination falls back to the used range; the manual-break lists parallel their break lists.
set_formula() rejects malformed formula text with the kParserUnexpectedToken host status and leaves the previous formula and cached value unchanged. A malformed formula already stored in an XLSX or XLSB file remains loadable; after recalc() its cell value is #NAME?. The one-shot eval_formula() helper follows the ad-hoc path and returns #NAME? as a value for malformed input.
iter_cells(sheet) enumerates written coordinates, including styled blanks, set_blank writes, and spill phantoms, in (row, col) order. Unwritten gaps are omitted. Do not mutate the sheet during iteration. Unlike get_cells_in_range(), this includes explicitly written blank cells; see Inspect a range.
Serialization diagnostics
save_with_diagnostics(fmt) returns a SaveDiagnostics object with the saved bytes and counters for losses and deferred features observed by the writer. read_diagnostics() returns a ReadDiagnostics object with the counters captured when the workbook was loaded. The counters have partial coverage: an all-zero result means that none of the documented losses occurred, not that the package was compared byte-for-byte or that no diagnostic event was logged.
| Result | Fields | Meaning |
|---|---|---|
SaveDiagnostics | downgraded_formula_count | Formula cells emitted as cached literals; always zero for XLSX. |
deferred_feature_count | Sheet features not lowered to records; always zero for XLSX. | |
dropped_part_count | Passthrough parts dropped by either writer. | |
dropped_relationship_count | Relationships dropped because their target part was dropped; this can describe the same loss as dropped_part_count. | |
renumbered_part_count | Tables emitted under a writer-assigned part id; always zero for XLSB. | |
ReadDiagnostics | undecoded_formula_count | Stored formulas that could not be decoded; XLSB only. |
undecoded_defined_name_count | Defined names skipped because they could not be decoded; XLSB only. | |
undecoded_part_count | XLSB package parts whose content type could not be resolved. | |
skipped_feature_count | OOXML presentation-overlay entries skipped because their references were unusable. | |
unknown_content_type_count | OOXML workbook parts with an unrecognised content type. |
from formulon import Workbook, WorkbookFormat
with Workbook.create_default() as wb:
saved = wb.save_with_diagnostics(WorkbookFormat.XLSB)
print(saved.bytes, saved.downgraded_formula_count)
loaded = Workbook.load(saved.bytes)
try:
print(loaded.read_diagnostics().undecoded_formula_count)
finally:
loaded.close()dropped_part_count and dropped_relationship_count can both increase for one dropped part; do not add them as a total number of lost objects.
Pinned clock
NOW(), TODAY(), and pivot relative-period filters read the host clock when the workbook is unpinned. Pin the workbook to one local civil-time reading when those results must agree within a recalculation or be reproducible across hosts:
from formulon import Workbook
with Workbook.create_default() as wb:
wb.set_pinned_now(2026, 8, 19, 12, 0, 0)
print(wb.pinned_now()) # CivilTime(year, month, day, hour, minute, second)
wb.recalc()
wb.clear_pinned_now()pinned_now() returns a CivilTime object or None when the workbook follows the host clock. set_pinned_now() validates year 1900–9999, the real day range for month 1–12, hour 0–23, and minute / second 0–59; invalid fields raise FormulonError rather than being normalised. The values are local civil fields, not a timestamp, so they have no timezone interpretation. Setting or clearing the pin does not recalculate cached formula values; call recalc() explicitly. The pin is workbook model state, not file state: saving does not record it, and a reloaded workbook is unpinned.
Values
Value.to_python() converts blank, number, boolean, and text values into natural Python types (None, float, bool, str). Error, array, ref, and lambda values return the Value wrapper so callers can inspect kind and payload fields.
value = wb.get_value(0, 0, 0)
if value.kind is ValueKind.NUMBER:
print(value.number)
elif value.kind is ValueKind.ERROR:
print(formulon.error_display_name(value.error_code))Value validates its payload on construction. kind is coerced to ValueKind; a payload the kind does not take, or a missing one, raises ValueError, and a payload of the wrong type raises TypeError. Value(ValueKind.NUMBER) and Value(ValueKind.BLANK, text="a") therefore fail, and a bool is not accepted as a number.
Python's Value only carries error_code — there is no error_text field. Call formulon.error_display_name(value.error_code) to get the Excel literal (#DIV/0!, #VALUE!, …).
Error handling
FormulonError is a host-side failure: invalid bytes, an out-of-range index, malformed text passed to set_formula(), use after close(), or an internal engine failure. It carries status (the numeric fm_status_t), status_name (for example kParserUnexpectedToken), message, and context. An integer argument that is fractional or does not fit the C ABI's integer width, such as a negative sheet index, raises ValueError before the engine is called; packed integer arguments are range-checked the same way. Excel cell errors are values, not exceptions:
import formulon
from formulon import Workbook, ValueKind, FormulonError
try:
with Workbook.load(blob) as wb:
wb.recalc()
v = wb.get_value(0, 0, 0)
if v.kind is ValueKind.ERROR:
handle_cell_error(v)
except FormulonError as e:
handle_host_failure(e)Read next
- Workbook lifecycle — open / mutate / recalc / save.
- Presentation and geometry — display text, themes, styles, dimensions, and pagination.
- Filters and validation — AutoFilter state and proposed-value checks.
- Comments and images — threaded comments, persons, drawing objects, and pictures.
- Python batch recalculation — end-to-end pipeline.