Skip to content

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):

AreaEnums
ValuesErrorCode (NULL = 0, DIV0 = 1, … UNKNOWN = 16)
Geometry and displayGeometryMode (DISPLAY = 0, PRINT = 1), DisplayStatus (OK = 0, OVERFLOW = 1, INVALID_FORMAT = 2)
AutoFilterFilterKind, FilterOperator, DynamicFilterType, SortBy, SortMethod, DateTimeGrouping
ValidationValidationErrorStyle (STOP = 0, WARNING = 1, INFORMATION = 2)
Themes and stylesColorContext, ColorResolution, ThemeSource, EffectiveStyleSource
Images and drawingsImageFormat, DrawingObjectKind, AnchorKind, AnchorEditAs
PivotTablesPivotAxis, PivotAggregation, PivotShowValuesAs, PivotFilterType, PivotFilterValueKind, PivotDateGrouping, PivotCalendar, PivotReportLayout, PivotCellKind
Text collationCollationStrength (COMPARE = 0, DYNAMIC = 1, CLASSIC_EXACT = 2)
Workbook stateCalcMode, SheetVisibility, WorkbookFormat, ExternalLinkKind
LoggingLogLevel (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 ​

python
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:

python
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.

python
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 ​

NameSignatureDescription
formulon.library_versionlibrary_version() -> strReturn the version string baked into the loaded WASM module.
formulon.version_stringversion_string() -> strAlias of library_version().
formulon.error_display_nameerror_display_name(error_code: int) -> strReturn an Excel literal such as "#DIV/0!" for an error code.
formulon.set_log_min_levelset_log_min_level(level: Union[LogLevel, int]) -> NoneSet the engine's minimum structured-log severity.

Workbook lifecycle and I/O ​

NameSignatureDescription
Workbook.create_defaultcreate_default() -> WorkbookBuild a default workbook (a single sheet named Sheet1).
Workbook.create_for_profilecreate_for_profile(profile_id: str) -> WorkbookBuild a new workbook with the defaults of an Excel profile.
Workbook.create_emptycreate_empty() -> WorkbookBuild an empty workbook (no sheets).
Workbook.loadload(data: Union[bytes, bytearray, memoryview]) -> WorkbookLoad a workbook from an in-memory byte buffer.
closeclose() -> NoneRelease the underlying handle.
is_validis_valid: boolTrue while the handle is still alive.
memory_usagememory_usage() -> intReturn an estimate of the workbook's heap footprint, in bytes.
savesave() -> bytesSerialise the workbook to an in-memory .xlsx byte stream.
save_assave_as(fmt: Union[WorkbookFormat, int]) -> bytesSerialise the workbook to an in-memory byte stream in fmt.
save_with_diagnosticssave_with_diagnostics(fmt: Union[WorkbookFormat, int]) -> SaveDiagnosticsSerialise the workbook and return what the save cost.
read_diagnosticsread_diagnostics() -> ReadDiagnosticsReturn the loss counters captured when this workbook was loaded.
iter_passthroughiter_passthrough() -> Iterator[PassthroughPart]Iterate over passthrough OOXML part paths.

Sheets and structure ​

NameSignatureDescription
sheet_countsheet_count() -> intNumber of sheets in the workbook.
active_sheetactive_sheet() -> intIndex of the active sheet (activeTab of the first workbook view).
set_active_sheetset_active_sheet(index: int) -> NoneMark the sheet at index active so save records it.
sheet_namesheet_name(index: int) -> strDisplay name (UTF-8) of the sheet at index.
add_sheetadd_sheet(name: str) -> NoneAppend a new sheet with the given UTF-8 display name.
move_sheetmove_sheet(from_index: int, to_index: int) -> NoneMove the sheet at from_index to to_index (post-removal).
remove_sheetremove_sheet(index: int) -> NoneRemove the sheet at index.
rename_sheetrename_sheet(index: int, new_name: str) -> NoneRename the sheet at index to new_name.
insert_rowsinsert_rows(sheet: int, row: int, count: int) -> NoneInsert count rows at row on sheet.
delete_rowsdelete_rows(sheet: int, row: int, count: int) -> NoneDelete count rows starting at row on sheet.
insert_colsinsert_cols(sheet: int, col: int, count: int) -> NoneInsert count columns at col on sheet.
delete_colsdelete_cols(sheet: int, col: int, count: int) -> NoneDelete count columns starting at col on sheet.

Cells ​

NameSignatureDescription
set_numberset_number(sheet: int, row: int, col: int, value: float) -> NoneStore the number value at (sheet, row, col).
set_boolset_bool(sheet: int, row: int, col: int, value: bool) -> NoneStore the boolean value at (sheet, row, col).
set_errorset_error(sheet: int, row: int, col: int, error_code: int) -> NoneStore an Excel cell error at (sheet, row, col).
set_textset_text(sheet: int, row: int, col: int, value: str) -> NoneStore the string value at (sheet, row, col).
set_blankset_blank(sheet: int, row: int, col: int) -> NoneClear the cell at (sheet, row, col).
set_formulaset_formula(sheet: int, row: int, col: int, formula: str) -> NoneStore the formula formula at (sheet, row, col).
set_phoneticset_phonetic(sheet: int, row: int, col: int, text: str) -> NoneSet the cell's phonetic guide (OOXML <rPh>, furigana).
set_phonetic_runsset_phonetic_runs(sheet: int, row: int, col: int, runs: Sequence[PhoneticRun]) -> NoneSet the cell's phonetic guide as one <rPh> block per run.
get_phoneticget_phonetic(sheet: int, row: int, col: int) -> strReturn the cell's phonetic guide, or "" when it has none.
get_phonetic_runsget_phonetic_runs(sheet: int, row: int, col: int) -> List[PhoneticRun]Return the cell's <rPh> blocks, spans included.
set_phonetic_propertiesset_phonetic_properties(sheet: int, row: int, col: int, properties: PhoneticProperties) -> NoneSet how the cell's phonetic guide renders.
get_phonetic_propertiesget_phonetic_properties(sheet: int, row: int, col: int) -> PhoneticPropertiesReturn how the cell's phonetic guide renders.
has_phonetic_propertieshas_phonetic_properties(sheet: int, row: int, col: int) -> boolWhether the cell's phonetic properties are explicit.
get_valueget_value(sheet: int, row: int, col: int) -> ValueRead the cached value at (sheet, row, col).
lambda_text_atlambda_text_at(sheet: int, row: int, col: int) -> strRender the lambda cached at (sheet, row, col) as text.
iter_cellsiter_cells(sheet: int) -> Iterator[Cell]Iterate over every written coordinate on sheet.
get_formulaget_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_r1c1get_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_rangeget_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 ​

NameSignatureDescription
recalcrecalc() -> NoneDrive a full incremental recalc.
set_iterativeset_iterative(enabled: bool, max_iterations: int, max_change: float) -> NoneConfigure iterative calculation.
set_iterative_enabledset_iterative_enabled(enabled: bool) -> NoneToggle iterative calculation, keeping the cap and threshold.
get_iterativeget_iterative() -> IterativeSettingsRead back the iterative-calculation settings.
partial_recalcpartial_recalc(sheet: int, first_row: int, last_row: int, first_col: int, last_col: int) -> intRecalc the dependency closure for a viewport; return cell count.
calc_modecalc_mode() -> CalcModeReturn the workbook's calc mode (round-trip metadata).
full_precisionfull_precision() -> boolReturn <calcPr fullPrecision>; false is "set precision as displayed" (metadata only).
set_full_precisionset_full_precision(full_precision: bool) -> NoneSet <calcPr fullPrecision>.
calc_on_savecalc_on_save() -> boolReturn <calcPr calcOnSave> (default true).
set_calc_on_saveset_calc_on_save(calc_on_save: bool) -> NoneSet <calcPr calcOnSave>.
ref_moderef_mode() -> RefModeReturn <calcPr refMode>: the reference notation formulas are shown in.
set_ref_modeset_ref_mode(mode: Union[RefMode, int]) -> NoneSet <calcPr refMode>.
date1904date1904() -> boolReturn whether the workbook uses the 1904 date system.
set_date1904set_date1904(date1904: bool) -> NoneSwitch the date system.
set_calc_modeset_calc_mode(mode: Union[CalcMode, int]) -> NoneSet the workbook's calc mode.
pinned_nowpinned_now() -> Optional[CivilTime]Return the pinned wall-clock reading, or None when the
set_pinned_nowset_pinned_now(year: int, month: int, day: int, hour: int = ..., minute: int = ..., second: int = ...) -> NonePin every clock-dependent result to one instant.
clear_pinned_nowclear_pinned_now() -> NoneRelease the pin so clock-dependent results follow the host clock
add_data_tableadd_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]] = ...) -> NoneCreate a data table whose result range is first_row..last_col (0-based, inclusive).
get_data_tableget_data_table(sheet: int, row: int, col: int) -> Optional[DataTable]Return the data table whose result range contains (row, col), or None.
remove_data_tableremove_data_table(sheet: int, row: int, col: int) -> NoneRemove the data table containing (row, col) and blank its result cells.
recalc_data_tablesrecalc_data_tables() -> NoneRecompute every data table now, whatever the calc mode (the explicit calculation of AUTO_NO_TABLE).

Read-only evaluation ​

NameSignatureDescription
evaluate_formula_arrayevaluate_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_formulaevaluate_cf_formula(sheet: int, row: int, col: int, anchor_row: int, anchor_col: int, formula: str) -> boolEvaluate a conditional-format formula at one cell without mutation.
formulon.eval_formulaeval_formula(formula: str) -> ValueEvaluate a single formula against a fresh, default workbook.

Profiles, locale and text ​

NameSignatureDescription
formulon.merge_function_metadatamerge_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_idexcel_profile_id() -> ExcelProfileIdReturn the active Excel formula profile id.
set_excel_profile_idset_excel_profile_id(profile_id: ExcelProfileId) -> NoneSet the workbook's Excel formula profile by id.
Workbook.function_countfunction_count() -> intReturn the total number of registered Formulon functions.
Workbook.function_name_atfunction_name_at(index: int) -> strReturn the canonical name of the index-th function.
Workbook.function_metadatafunction_metadata(name: str) -> Optional[FunctionMetadata]Return metadata for name or None when unknown.
Workbook.localize_function_namelocalize_function_name(canonical_name: str, profile_id: ExcelProfileId) -> strReturn the display name of canonical_name under profile_id.
Workbook.canonicalize_function_namecanonicalize_function_name(localized_name: str, profile_id: ExcelProfileId) -> strReturn the canonical English name for localized_name under profile_id.
Workbook.localize_formulalocalize_formula(formula: str, profile_id: ExcelProfileId) -> strRewrite stored (en-invariant) formula text into profile_id's spelling.
Workbook.canonicalize_formulacanonicalize_formula(formula: str, profile_id: ExcelProfileId) -> strRewrite profile_id-spelled formula text into the en-invariant form.
Workbook.locale_factslocale_facts(profile_id: ExcelProfileId) -> LocaleFactsReturn the locale facts (separators, names, currency, error names) of profile_id.
Workbook.compare_textcompare_text(a: str, b: str, strength: CollationStrength, profile_id: ExcelProfileId) -> intCompare two texts under the collation of profile_id.
Workbook.collation_classescollation_classes(values: Sequence[Value], strength: CollationStrength, profile_id: ExcelProfileId) -> CollationClassesClassify values into collation-ordered equivalence classes.

Defined names ​

NameSignatureDescription
set_defined_nameset_defined_name(name: str, formula: str) -> NoneSet, append, or remove a workbook-scoped defined name.
set_defined_name_scopedset_defined_name_scoped(name: str, formula: str, local_sheet_id: int) -> NoneSet, append, or remove a defined name in workbook or sheet scope.
set_defined_name_attrsset_defined_name_attrs(name: str, local_sheet_id: int = ..., *, comment: Optional[str] = ..., hidden: Optional[bool] = ...) -> NoneSet the comment and / or hidden attribute of an existing defined name.
iter_defined_namesiter_defined_names() -> Iterator[DefinedName]Iterate over every defined name in declaration order.

Tables ​

NameSignatureDescription
iter_tablesiter_tables() -> Iterator[Table]Iterate over every table in declaration order.
table_createtable_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] = ...) -> intCreate a worksheet table and return its index.
table_set_style_infotable_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 = ...) -> NoneSet the table's style name and toggles, making the style element present.
table_renametable_rename(index: int, name: str, display_name: Optional[str] = ...) -> NoneRename table index; display_name=None uses name for both.
table_set_column_totalstable_set_column_totals(index: int, column: int, function: Optional[str] = ..., label: Optional[str] = ..., formula: Optional[str] = ...) -> NoneSet column column's totals-row function and label.
table_updatetable_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] = ...) -> NoneReplace a table's range and optional visual style.
table_removetable_remove(index: int) -> NoneRemove the table at index.
table_style_counttable_style_count() -> intReturn the number of custom table / PivotTable styles.
get_table_styleget_table_style(index: int) -> TableStyleReturn the custom table style at index.
set_table_styleset_table_style(style: TableStyle) -> NoneAdd a custom table style, or replace the one with the same name.
remove_table_styleremove_table_style(name: str) -> NoneRemove the custom table style name.
table_style_defaultstable_style_defaults() -> Tuple[str, str]Return the default (table_style, pivot_style) names; empty when unset.
set_table_style_defaultsset_table_style_defaults(table_style: Optional[str] = ..., pivot_style: Optional[str] = ...) -> NoneSet the default style names; None keeps one, "" removes it.

Dependencies, spills and external links ​

NameSignatureDescription
precedentsprecedents(sheet: int, row: int, col: int, depth: int = ...) -> List[CellNode]Return the cells (sheet, row, col) reads (up to depth).
dependentsdependents(sheet: int, row: int, col: int, depth: int = ...) -> List[CellNode]Return the cells that read (sheet, row, col) (up to depth).
spill_infospill_info(sheet: int, row: int, col: int) -> SpillInfoReturn dynamic-array spill info for (sheet, row, col).
external_link_countexternal_link_count() -> intReturn the number of external-link records on the workbook.
get_external_link_atget_external_link_at(index: int) -> ExternalLinkRead the index-th external-link record.
get_external_linksget_external_links() -> List[ExternalLink]Return every external-link record in document order.

Sheet view and protection ​

NameSignatureDescription
get_show_phoneticget_show_phonetic(sheet: int, row: int, col: int) -> boolWhether the cell shows its phonetic guide (<c ph="1">).
set_show_phoneticset_show_phonetic(sheet: int, row: int, col: int, show: bool) -> NoneSet the cell's "Show Phonetic" display flag.
get_workbook_protectionget_workbook_protection() -> WorkbookProtectionRead the workbook's <workbookProtection>; every field is false, empty or zero when absent.
set_workbook_protectionset_workbook_protection(protection: WorkbookProtection) -> NoneReplace the modelled <workbookProtection> attributes; an all-empty record removes the element.
protected_range_countprotected_range_count(sheet: int) -> intReturn the number of protected ranges on sheet.
get_protected_rangesget_protected_ranges(sheet: int) -> List[ProtectedRange]Return the protected ranges of sheet in file order.
add_protected_rangeadd_protected_range(sheet: int, protected: ProtectedRange) -> NoneAppend a protected range; name must be non-empty and unique on the sheet.
update_protected_rangeupdate_protected_range(sheet: int, index: int, protected: ProtectedRange) -> NoneReplace the index-th protected range of sheet.
remove_protected_rangeremove_protected_range(sheet: int, index: int) -> NoneRemove the index-th protected range of sheet.
get_sheet_protectionget_sheet_protection(sheet: int) -> SheetProtectionRead the sheet's <sheetProtection> flags.
set_sheet_protectionset_sheet_protection(sheet: int, protection: SheetProtection) -> NoneReplace the sheet's <sheetProtection> flags wholesale.
get_sheet_viewget_sheet_view(sheet: int) -> SheetViewRead the full per-sheet view (zoom, freeze, tab-hidden, and the
set_sheet_zoomset_sheet_zoom(sheet: int, zoom_scale: int) -> NoneSet the sheet zoom percentage (clamped to [10, 400]).
set_sheet_freezeset_sheet_freeze(sheet: int, freeze_rows: int, freeze_cols: int) -> NoneSet the frozen pane in (rows, cols).
set_sheet_tab_hiddenset_sheet_tab_hidden(sheet: int, hidden: bool) -> NoneSet the sheet tab's hidden flag.
set_sheet_visibilityset_sheet_visibility(sheet: int, visibility: Union[SheetVisibility, int]) -> NoneSet the sheet tab's visibility to one of the three states.
set_sheet_show_grid_linesset_sheet_show_grid_lines(sheet: int, show: bool) -> NoneSet the sheet's showGridLines flag.
set_sheet_show_row_col_headersset_sheet_show_row_col_headers(sheet: int, show: bool) -> NoneSet the sheet's showRowColHeaders flag.
set_sheet_show_zerosset_sheet_show_zeros(sheet: int, show: bool) -> NoneSet the sheet's showZeros flag.
set_sheet_show_formulasset_sheet_show_formulas(sheet: int, show: bool) -> NoneSet the sheet's showFormulas flag.
set_sheet_show_outline_symbolsset_sheet_show_outline_symbols(sheet: int, show: bool) -> NoneSet the sheet's showOutlineSymbols flag.
set_sheet_right_to_leftset_sheet_right_to_left(sheet: int, right_to_left: bool) -> NoneSet the sheet's rightToLeft flag.
set_sheet_tab_selectedset_sheet_tab_selected(sheet: int, selected: bool) -> NoneSet the sheet's tabSelected flag.
set_sheet_top_leftset_sheet_top_left(sheet: int, row: int, col: int) -> NoneSet the sheet view's scroll origin (topLeftCell).
set_sheet_pane_top_leftset_sheet_pane_top_left(sheet: int, row: int, col: int) -> NoneSet the first visible cell of a frozen or split view's lower-right pane.
set_sheet_splitset_sheet_split(sheet: int, x_twips: float, y_twips: float) -> NoneSplit the view at x_twips / y_twips (0 for none on that axis).
get_sheet_selectionget_sheet_selection(sheet: int) -> Tuple[Tuple[int, int], List[MergeRange]]Return ((active_row, active_col), ranges) of the active pane's selection.
set_sheet_selectionset_sheet_selection(sheet: int, active_row: int, active_col: int, ranges: Sequence[MergeRange] = ...) -> NoneReplace the active pane's selection; no ranges selects the active cell alone.
set_sheet_view_modeset_sheet_view_mode(sheet: int, mode: str) -> NoneSet the sheet's <sheetView view="..."> mode: "",

Rows, columns and geometry ​

NameSignatureDescription
get_sheet_columnsget_sheet_columns(sheet: int) -> List[ColumnLayout]Return the column-layout overrides on sheet.
set_column_widthset_column_width(sheet: int, first: int, last: int, width: float) -> NoneSet the column width override on [first, last].
set_column_hiddenset_column_hidden(sheet: int, first: int, last: int, hidden: bool) -> NoneSet the column hidden flag on [first, last].
set_column_outlineset_column_outline(sheet: int, first: int, last: int, level: int) -> NoneSet the column outline level (0-7) on [first, last].
set_column_collapsedset_column_collapsed(sheet: int, first: int, last: int, collapsed: bool) -> NoneSet or clear the collapsed flag on the columns [first, last].
get_sheet_row_overridesget_sheet_row_overrides(sheet: int) -> List[RowLayout]Return the row-layout overrides on sheet.
set_row_heightset_row_height(sheet: int, row: int, height: float) -> NoneSet the row height override at row.
clear_row_heightclear_row_height(sheet: int, row: int) -> NoneRemove the height override at row (back to the sheet default).
set_column_styleset_column_style(sheet: int, first: int, last: int, xf_index: int) -> NoneSet the cell-style XF on [first, last], keeping the other column attributes.
clear_column_styleclear_column_style(sheet: int, first: int, last: int) -> NoneRemove the cell-style XF on [first, last], keeping the other column attributes.
set_row_styleset_row_style(sheet: int, first: int, last: int, xf_index: int) -> NoneSet the cell-style XF on the inclusive row span first..last, keeping the other row attributes.
clear_row_styleclear_row_style(sheet: int, first: int, last: int) -> NoneRemove the cell-style XF on the inclusive row span first..last, keeping the other row attributes.
clear_column_widthclear_column_width(sheet: int, first: int, last: int) -> NoneRemove the width override on [first, last] (back to the sheet default).
get_sheet_format_defaultsget_sheet_format_defaults(sheet: int) -> SheetFormatDefaultsRead the sheet's default column / row metrics (<sheetFormatPr>).
set_sheet_format_defaultsset_sheet_format_defaults(sheet: int, defaults: SheetFormatDefaults) -> NoneReplace the sheet's default column / row metrics; a None flag keeps the stored one.
get_cell_rect_ptget_cell_rect_pt(sheet: int, cell_range: MergeRange, mode: Union[GeometryMode, int] = ...) -> RectPtReturn the rectangle covering cell_range in points from the top-left of A1.
get_column_width_ptget_column_width_pt(sheet: int, col: int, mode: Union[GeometryMode, int] = ...) -> floatReturn the effective width of col in points (0 when hidden).
get_row_height_ptget_row_height_pt(sheet: int, row: int) -> floatReturn the effective height of row in points (0 when hidden).
get_width_modelget_width_model(sheet: int, mode: Union[GeometryMode, int] = ...) -> WidthModelReturn the character-unit to point conversion model in mode.
column_chars_to_ptcolumn_chars_to_pt(sheet: int, chars: float, mode: Union[GeometryMode, int] = ...) -> floatConvert a stored column width (padding included) to points, snapped to whole screen pixels.
column_pt_to_charscolumn_pt_to_chars(sheet: int, pt: float, mode: Union[GeometryMode, int] = ...) -> floatConvert points to the stored column width Excel writes for that column.
set_row_hiddenset_row_hidden(sheet: int, row: int, hidden: bool) -> NoneSet the row hidden flag at row.
set_row_outlineset_row_outline(sheet: int, row: int, level: int) -> NoneSet the row outline level (0-7) at row.
set_row_collapsedset_row_collapsed(sheet: int, row: int, collapsed: bool) -> NoneSet or clear the collapsed flag at row.

Display text ​

NameSignatureDescription
get_display_textget_display_text(sheet: int, row: int, col: int) -> Tuple[str, DisplayStatus]Return the text Excel displays for the cell and the rendering outcome.
format_valueformat_value(value: Value, format_code: str = ...) -> Tuple[str, DisplayStatus]Render value under the number format format_code (empty means General).

Styles ​

NameSignatureDescription
range_style_basesrange_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_styleremap_range_style(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int, mapping: Dict[int, int]) -> NoneRemap the XFs of a selection: a cell resolving to key k ends at mapping[k].
snapshot_range_stylesnapshot_range_style(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int) -> bytesCapture the style state of a selection as opaque bytes for restore_range_style.
restore_range_stylerestore_range_style(sheet: int, data: Union[bytes, bytearray, memoryview]) -> NonePut a snapshot_range_style capture back on sheet.
get_cell_xf_indexget_cell_xf_index(sheet: int, row: int, col: int) -> intReturn the xf (style record) index attached to a cell.
set_cell_xf_indexset_cell_xf_index(sheet: int, row: int, col: int, xf_index: int) -> NoneStore xf_index on the cell at (row, col).
clear_cell_xf_indexclear_cell_xf_index(sheet: int, row: int, col: int) -> NoneRemove the direct style assignment from the cell at (row, col).
set_range_xf_indexset_range_xf_index(sheet: int, first_row: int, first_col: int, last_row: int, last_col: int, xf_index: int) -> NoneStore xf_index on every cell in the inclusive rectangle.
get_cell_xfget_cell_xf(xf_index: int) -> CellXfReturn the resolved <xf> record at xf_index.
get_fontget_font(font_index: int) -> FontRecordReturn the font record at font_index.
get_fillget_fill(fill_index: int) -> FillRecordReturn the fill record at fill_index.
get_borderget_border(border_index: int) -> Dict[str, object]Return the border record at border_index.
get_dxfget_dxf(dxf_index: int) -> DifferentialFormatRead one differential format by its conditional-format dxfId.
get_num_fmtget_num_fmt(num_fmt_id: int) -> strReturn the format code registered for num_fmt_id.
font_countfont_count() -> intReturn the number of font records registered.
fill_countfill_count() -> intReturn the number of fill records registered.
border_countborder_count() -> intReturn the number of border records registered.
cell_xf_countcell_xf_count() -> intReturn the number of <xf> records registered.
cell_style_countcell_style_count() -> intReturn the number of named cell styles.
cell_style_xf_countcell_style_xf_count() -> intReturn the number of <cellStyleXfs> records.
dxf_countdxf_count() -> intReturn the number of differential formats available to CF rules.
add_fontadd_font(record: FontRecord) -> intAdd (dedup) a font record; return its index.
set_fontset_font(font_index: int, record: FontRecord) -> NoneOverwrite an existing font slot in place.
set_default_fontset_default_font(record: FontRecord) -> NoneDeclare the workbook's default font (font 0).
add_filladd_fill(record: FillRecord) -> intAdd (dedup) a fill record; return its index.
add_borderadd_border(sides: Dict[str, object]) -> intAdd (dedup) a border record; return its index.
add_num_fmtadd_num_fmt(format_code: str) -> intAdd (dedup) a number-format code; return its resolved id.
add_cell_xfadd_cell_xf(record: CellXf) -> intAdd (dedup) an <xf> record; return its index.
add_cell_style_xfadd_cell_style_xf(record: CellXf) -> intAdd (dedup) a named-style <xf>; return its <cellStyleXfs> id.
add_batchadd_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]] = ...) -> StyleBatchIndicesAdd (dedup) whole style tables in one call.
add_dxfadd_dxf(record: DifferentialFormat) -> intAdd (dedup) a differential format and return its dxfId.
set_cell_styleset_cell_style(record: CellStyle) -> NoneAdd or replace the named <cellStyle> record record.name.
remove_cell_styleremove_cell_style(name: str) -> NoneRemove the named cell style name.
get_effective_styleget_effective_style(sheet: int, row: int, col: int) -> EffectiveStyleRead the effective style of the cell at (row, col); the cell need not exist.
get_cell_styleget_cell_style(index: int) -> CellStyleReturn the named cell style at index.
get_cell_style_xfget_cell_style_xf(index: int) -> CellXfReturn the named-style xf record at index.

Themes and colors ​

NameSignatureDescription
get_themeget_theme() -> ThemeRead the theme's 12 scheme colours and typefaces.
set_theme_colorsset_theme_colors(colors: Sequence[int]) -> NoneReplace the theme's 12 scheme colours (a:clrScheme order; alpha ignored).
set_theme_fontsset_theme_fonts(fonts: ThemeFonts) -> NoneReplace the theme's major and minor typefaces.
set_theme_script_fontset_theme_script_font(major: bool, script: str, typeface: str) -> NoneSet the typeface of one script in the major (heading) or minor (body) font set.
reset_themereset_theme() -> NoneRemove the theme part so the workbook reports the default theme.
resolve_colorresolve_color(spec: ColorSpec, context: Union[ColorContext, int] = ...) -> ResolvedColorResolve spec to the 0xAARRGGBB Excel renders.

Merges ​

NameSignatureDescription
add_mergeadd_merge(sheet: int, merge: MergeRange) -> NoneAppend a merge range to sheet.
remove_mergeremove_merge(sheet: int, merge: MergeRange) -> NoneRemove every merge on sheet overlapping merge.
remove_merge_atremove_merge_at(sheet: int, index: int) -> NoneRemove the merge at index on sheet.
clear_mergesclear_merges(sheet: int) -> NoneDrop every merge range on sheet.
merge_countmerge_count(sheet: int) -> intReturn the number of merge ranges on sheet.
get_mergesget_merges(sheet: int) -> List[MergeRange]Return every merge range on sheet.
get_merges_in_rangeget_merges_in_range(sheet: int, cell_range: MergeRange) -> List[MergeRange]Return every merge range on sheet that intersects cell_range.
NameSignatureDescription
add_hyperlinkadd_hyperlink(sheet: int, row: int, col: int, target: str, display: str = ..., tooltip: str = ..., location: str = ...) -> NoneAppend a hyperlink to sheet.
add_hyperlink_rangeadd_hyperlink_range(sheet: int, row: int, col: int, last_row: int, last_col: int, target: str, display: str = ..., tooltip: str = ..., location: str = ...) -> NoneAppend a hyperlink covering the inclusive cell rectangle.
remove_hyperlinkremove_hyperlink(sheet: int, row: int, col: int) -> NoneRemove every hyperlink anchored at (row, col) on sheet.
remove_hyperlink_atremove_hyperlink_at(sheet: int, index: int) -> NoneRemove the hyperlink at index on sheet.
clear_hyperlinksclear_hyperlinks(sheet: int) -> NoneDrop every hyperlink on sheet.
hyperlink_counthyperlink_count(sheet: int) -> intReturn the number of hyperlinks on sheet.
get_hyperlinksget_hyperlinks(sheet: int) -> List[Hyperlink]Return every hyperlink on sheet.
get_commentget_comment(sheet: int, row: int, col: int) -> Optional[Comment]Return the comment at (sheet, row, col) or None if absent.
set_commentset_comment(sheet: int, row: int, col: int, author: str, text: str) -> NoneSet, replace, or (empty text) remove a cell comment.
get_comment_visibleget_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_visibleset_comment_visible(sheet: int, row: int, col: int, visible: bool) -> NoneShow or hide the note at the cell; its box geometry is kept.
comment_countcomment_count(sheet: int) -> intReturn the number of comments on sheet.
get_commentsget_comments(sheet: int) -> List[CommentEntry]Return every comment on sheet in storage order.

Threaded comments and persons ​

NameSignatureDescription
get_threaded_commentsget_threaded_comments(sheet: int) -> List[ThreadedComment]Return the sheet's threaded comments in file order (openers followed by their replies).
add_threaded_commentadd_threaded_comment(sheet: int, comment: ThreadedComment) -> NoneAdd a threaded comment: a new thread when parent_id is empty, else a reply.
edit_threaded_commentedit_threaded_comment(sheet: int, comment_id: str, text: str, mentions: Sequence[Mention] = ...) -> NoneReplace the text and mentions of the comment comment_id.
set_thread_resolvedset_thread_resolved(sheet: int, thread_id: str, done: bool) -> NoneSet the resolved state of the thread opened by thread_id.
remove_threaded_commentremove_threaded_comment(sheet: int, comment_id: str) -> NoneRemove the comment comment_id; removing a thread opener removes its whole thread.
get_personsget_persons() -> List[Person]Return the workbook's person list in file order.
add_personadd_person(person: Person) -> NoneAppend a person to the workbook's person list.
remove_personremove_person(person_id: str) -> NoneRemove the person person_id (refused while a comment or mention still names them).

AutoFilter ​

NameSignatureDescription
get_auto_filter_xmlget_auto_filter_xml(sheet: int) -> strReturn the sheet's <autoFilter> XML fragment, or "".
set_auto_filter_xmlset_auto_filter_xml(sheet: int, xml: str) -> NoneReplace the sheet's <autoFilter> XML fragment.
get_auto_filterget_auto_filter(sheet: int) -> Optional[AutoFilter]Return the sheet AutoFilter, or None when the sheet has none.
set_auto_filterset_auto_filter(sheet: int, auto_filter: AutoFilter) -> NoneReplace the sheet AutoFilter.
remove_auto_filterremove_auto_filter(sheet: int) -> NoneRemove the sheet AutoFilter (no-op when absent).
apply_auto_filterapply_auto_filter(sheet: int) -> NoneHide the body rows the sheet AutoFilter excludes and show the rest.
clear_auto_filterclear_auto_filter(sheet: int) -> NoneDrop every column criterion of the sheet AutoFilter and show all its body rows.
evaluate_auto_filterevaluate_auto_filter(sheet: int) -> Tuple[int, List[bool]]Evaluate the sheet AutoFilter without changing the sheet.
get_table_auto_filterget_table_auto_filter(table_index: int) -> Optional[AutoFilter]Return the AutoFilter of table table_index, or None when it has none.
set_table_auto_filterset_table_auto_filter(table_index: int, auto_filter: AutoFilter) -> NoneReplace the AutoFilter of table table_index.
remove_table_auto_filterremove_table_auto_filter(table_index: int) -> NoneRemove the AutoFilter of table table_index (no-op when absent).
apply_table_auto_filterapply_table_auto_filter(table_index: int) -> NoneHide the body rows the table AutoFilter excludes and show the rest.
clear_table_auto_filterclear_table_auto_filter(table_index: int) -> NoneDrop every column criterion of the table AutoFilter and show all its body rows.
evaluate_table_auto_filterevaluate_table_auto_filter(table_index: int) -> Tuple[int, List[bool]]Evaluate the table AutoFilter; returns (first_row, match) as evaluate_auto_filter.

Data validation ​

NameSignatureDescription
validation_countvalidation_count(sheet: int) -> intReturn the number of data-validation rules on sheet.
get_validation_atget_validation_at(sheet: int, index: int) -> DataValidationRead the index-th data-validation rule on sheet.
get_validationsget_validations(sheet: int) -> List[DataValidation]Return every data-validation rule on sheet.
add_validationadd_validation(sheet: int, validation: DataValidationInput) -> NoneAppend a data-validation rule to sheet.
remove_validation_atremove_validation_at(sheet: int, index: int) -> NoneRemove the validation rule at index on sheet.
clear_validationsclear_validations(sheet: int) -> NoneDrop every validation rule on sheet.
validate_valuevalidate_value(sheet: int, row: int, col: int, value: Value) -> ValidationOutcomeCheck value against the data-validation rule covering (row, col) without storing it.
list_invalid_cellslist_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 ​

NameSignatureDescription
evaluate_cf_rangeevaluate_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_countcf_count(sheet: int) -> intReturn the number of CF rules on sheet (flattened).
get_conditional_format_atget_conditional_format_at(sheet: int, index: int) -> ConditionalFormatRead the index-th CF rule on sheet (flattened order).
get_conditional_formatsget_conditional_formats(sheet: int) -> List[ConditionalFormat]Return every CF rule on sheet in flattened priority order.
add_conditional_formatadd_conditional_format(sheet: int, rule: ConditionalFormatInput) -> intAppend a CF rule to sheet; return its index.
remove_conditional_format_atremove_conditional_format_at(sheet: int, index: int) -> NoneRemove the CF rule at index on sheet (flattened order).
clear_conditional_formatsclear_conditional_formats(sheet: int) -> NoneDrop every CF block on sheet.

Images and drawings ​

NameSignatureDescription
probe_imageprobe_image(data: Union[bytes, bytearray, memoryview]) -> ImageInfoSniff the format and pixel size of PNG, JPEG, GIF or BMP bytes without touching the workbook.
list_drawing_objectslist_drawing_objects(sheet: int) -> List[DrawingObject]Return the anchored objects of the sheet's drawing in document order.
get_imageget_image(sheet: int, object_id: int) -> bytesReturn the bytes of the picture object_id (copied out of WASM memory).
insert_imageinsert_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 = ...) -> intInsert an image anchored at (row, col) and return its object id.
remove_drawingremove_drawing(sheet: int, object_id: int) -> NoneRemove the picture or chart object_id and the parts only it reaches; other drawing content is kept.
set_drawing_anchorset_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 = ...) -> NoneMove and resize the picture or chart object_id, keeping its id and every other element.
set_drawing_z_orderset_drawing_z_order(sheet: int, object_id: int, index: int) -> NoneMake the picture or chart object_id item index of list_drawing_objects (0 is the back).
snapshot_drawingsnapshot_drawing(sheet: int, object_id: int) -> bytesCapture the picture or chart object_id as opaque bytes for restore_drawing.
restore_drawingrestore_drawing(sheet: int, data: Union[bytes, bytearray, memoryview], *, new_id: bool = ...) -> intPut a snapshot_drawing capture back and return the object's id.
list_shapeslist_shapes(sheet: int) -> List[Shape]Return the shapes, connectors and groups of the sheet's drawing in z-order (back first).
insert_shapeinsert_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] = ...) -> intAppend a shape on top of the sheet's drawing and return its object id.
update_shapeupdate_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] = ...) -> NoneApply the arguments that are not None to the shape object_id; the rest of its XML is kept.
remove_shaperemove_shape(sheet: int, object_id: int) -> NoneRemove the shape, connector or group object_id with its children.
list_slicerslist_slicers(sheet: int) -> List[Slicer]Return the table slicers hosted by the sheet; slicers over a pivot cache are not listed.
add_sliceradd_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]] = ...) -> intAdd a slicer over column column of table table and return its frame's object id.
update_slicerupdate_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]] = ...) -> NoneApply the arguments that are not None to slicer index; the rest of its XML is kept.
remove_slicerremove_slicer(sheet: int, index: int) -> NoneRemove slicer index with its drawing frame, and its cache when no other slicer uses it.
list_sparkline_groupslist_sparkline_groups(sheet: int) -> List[SparklineGroup]Return the sheet's sparkline groups in document order, each with its sparklines.
add_sparkline_groupadd_sparkline_group(sheet: int, group: SparklineGroup) -> NoneAppend group with its sparklines (at least one) to the sheet's worksheet extension list.
update_sparkline_groupupdate_sparkline_group(sheet: int, index: int, group: SparklineGroup) -> NoneRewrite the modelled attributes, colours and date range of group index from group.
set_sparkline_group_sparklinesset_sparkline_group_sparklines(sheet: int, index: int, sparklines: Sequence[Sparkline]) -> NoneReplace the sparklines of group index with sparklines (at least one).
remove_sparkline_groupremove_sparkline_group(sheet: int, index: int) -> NoneRemove sparkline group index.

Charts ​

NameSignatureDescription
get_chartget_chart(sheet: int, object_id: int) -> ChartInfoReturn the typed view of the chart object_id: plots, series, axes, legend and source.
get_chart_dataget_chart_data(sheet: int, object_id: int) -> ChartDataResolve the chart's series against the current cell values by Excel's rules.
preview_chart_datapreview_chart_data(sheet: int, object_id: int, overrides: Optional[ChartPreviewOverrides] = ...) -> ChartDataResolve the data of a copy of the chart with overrides applied; the workbook is unchanged.
insert_chartinsert_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 = ...) -> intCreate a chart over the A1 rectangle source and return its object id.
set_chart_typeset_chart_type(sheet: int, object_id: int, plot: int, kind: Union[ChartInsertKind, int], grouping: Union[ChartGrouping, int] = ...) -> NoneReplace plot group plot with kind, keeping each series' references, idx, order and explicit colors.
set_chart_titleset_chart_title(sheet: int, object_id: int, title: Union[str, None, ChartTitleInfo]) -> NoneSet the chart title to title; None removes it.
set_chart_legendset_chart_legend(sheet: int, object_id: int, position: Union[ChartLegendPosition, int], overlay: bool = ..., *, hidden_series: Optional[Sequence[int]] = ...) -> NoneSet the legend position (NONE removes it) and overlay.
set_chart_axisset_chart_axis(sheet: int, object_id: int, axis_id: int, patch: ChartAxisPatch) -> NonePatch axis axis_id: an omitted key is kept, None removes the element.
set_chart_displayset_chart_display(sheet: int, object_id: int, blanks_as: Union[ChartBlanksAs, int], plot_visible_only: Optional[bool]) -> NoneWrite how blanks plot and whether hidden cells are skipped; ABSENT / None remove the element.
set_chart_seriesset_chart_series(sheet: int, object_id: int, plot: int, series_idx: int, patch: ChartSeriesPatch) -> NonePatch the series with c:idx series_idx of plot group plot; a changed reference refreshes its cache.
set_chart_pointset_chart_point(sheet: int, object_id: int, plot: int, series_idx: int, point_idx: int, patch: Optional[ChartPointPatch]) -> NonePatch point point_idx of a series; None (or an empty patch) removes the point's formatting.
set_chart_plotset_chart_plot(sheet: int, object_id: int, plot: int, patch: ChartPlotPatch) -> NonePatch plot group plot; a field the plot type does not have is rejected.
set_chart_filterset_chart_filter(sheet: int, object_id: int, hidden_series: Sequence[int], hidden_categories: Sequence[int]) -> NoneReplace the chart filter: the listed series (by c:idx) and category positions are hidden.
add_chart_seriesadd_chart_series(sheet: int, object_id: int, plot: int, patch: ChartSeriesPatch) -> intAppend a series to plot group plot and return its c:idx.
remove_chart_seriesremove_chart_series(sheet: int, object_id: int, plot: int, series_idx: int) -> NoneRemove the series with c:idx series_idx from plot group plot.
set_chart_sourceset_chart_source(sheet: int, object_id: int, source: str, direction: Union[ChartSeriesDirection, int] = ..., header_row: Optional[bool] = ..., header_column: Optional[bool] = ...) -> NoneRebuild every series from source by the insert splitting rules.

Print settings and pagination ​

NameSignatureDescription
paginatepaginate(sheet: int) -> PaginationResultResolve the worksheet's print area, page breaks, and page count.
get_page_setup_xmlget_page_setup_xml(sheet: int) -> strReturn the sheet's <pageSetup> fragment, or "".
set_page_setup_xmlset_page_setup_xml(sheet: int, xml: str) -> NoneReplace the sheet's <pageSetup> fragment.
get_page_margins_xmlget_page_margins_xml(sheet: int) -> strReturn the sheet's <pageMargins> fragment, or "".
set_page_margins_xmlset_page_margins_xml(sheet: int, xml: str) -> NoneReplace the sheet's <pageMargins> fragment.
get_print_options_xmlget_print_options_xml(sheet: int) -> strReturn the sheet's <printOptions> fragment, or "".
set_print_options_xmlset_print_options_xml(sheet: int, xml: str) -> NoneReplace the sheet's <printOptions> fragment.
get_header_footer_xmlget_header_footer_xml(sheet: int) -> strReturn the sheet's <headerFooter> fragment, or "".
set_header_footer_xmlset_header_footer_xml(sheet: int, xml: str) -> NoneReplace the sheet's <headerFooter> fragment.
get_sheet_pr_xmlget_sheet_pr_xml(sheet: int) -> strReturn the sheet's <sheetPr> fragment, or "".
set_sheet_pr_xmlset_sheet_pr_xml(sheet: int, xml: str) -> NoneReplace the sheet's <sheetPr> fragment.
set_fit_to_pageset_fit_to_page(sheet: int, enabled: bool) -> NoneSet or clear <sheetPr><pageSetUpPr fitToPage>.
get_print_areaget_print_area(sheet: int) -> strReturn the print area as comma-separated A1 ranges, or "".
set_print_areaset_print_area(sheet: int, ranges_a1: str) -> NoneWrite _xlnm.Print_Area from one or more A1 ranges.
get_print_titlesget_print_titles(sheet: int) -> tuple[str, str]Return (repeat_rows, repeat_cols) as "1:2" / "A:A".
set_print_titlesset_print_titles(sheet: int, repeat_rows: str = ..., repeat_cols: str = ...) -> NoneWrite _xlnm.Print_Titles from a row span and a column span.
add_row_breakadd_row_break(sheet: int, row: int, manual: bool = ...) -> NoneUpsert a row break before row, spanning the whole sheet.
add_col_breakadd_col_break(sheet: int, col: int, manual: bool = ...) -> NoneUpsert a column break before col, spanning the whole sheet.
remove_row_breakremove_row_break(sheet: int, row: int) -> NoneRemove the row break at row.
remove_col_breakremove_col_break(sheet: int, col: int) -> NoneRemove the column break at col.
clear_breaksclear_breaks(sheet: int) -> NoneRemove every manual break on both axes.
get_row_breaksget_row_breaks(sheet: int) -> List[PageBreak]Return the row breaks, ascending by row.
get_col_breaksget_col_breaks(sheet: int) -> List[PageBreak]Return the column breaks, ascending by column.
set_page_setupset_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] = ...) -> NoneApply a partial <pageSetup> update.
set_page_marginsset_page_margins(sheet: int, *, left: Optional[float] = ..., right: Optional[float] = ..., top: Optional[float] = ..., bottom: Optional[float] = ..., header: Optional[float] = ..., footer: Optional[float] = ...) -> NoneApply a partial <pageMargins> update, in inches.
set_print_optionsset_print_options(sheet: int, *, grid_lines: Optional[bool] = ..., headings: Optional[bool] = ..., horizontal_centered: Optional[bool] = ..., vertical_centered: Optional[bool] = ...) -> NoneApply a partial <printOptions> update.
set_header_footerset_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] = ...) -> NoneApply a partial <headerFooter> update.
get_page_setupget_page_setup(sheet: int) -> PageSetupRead the effective page setup and which attributes state it.
get_page_marginsget_page_margins(sheet: int) -> PageMarginsRead the effective page margins in inches, with presence flags.

PivotTables ​

NameSignatureDescription
pivot_countpivot_count(sheet: int) -> intReturn the number of PivotTables anchored on sheet.
pivot_layoutpivot_layout(sheet: int, pivot_index: int) -> PivotLayoutEvaluate and project a PivotTable into concrete grid cells.
get_pivot_report_layoutget_pivot_report_layout(sheet: int, pivot_index: int) -> PivotReportLayoutReturn the pivot's compact, tabular, or outline report layout.
set_pivot_report_layoutset_pivot_report_layout(sheet: int, pivot_index: int, layout: Union[PivotReportLayout, int]) -> NoneSet the pivot's compact, tabular, or outline report layout.
pivot_createpivot_create(sheet: int, name: str, cache_id: int, anchor_row: int, anchor_col: int) -> intCreate a new empty pivot table; return its flat index.
pivot_removepivot_remove(sheet: int, pivot_index: int) -> NoneRemove the pivot table at pivot_index.
pivot_set_namepivot_set_name(sheet: int, pivot_index: int, name: str) -> NoneRename the pivot table.
pivot_set_anchorpivot_set_anchor(sheet: int, pivot_index: int, anchor_row: int, anchor_col: int, span_rows: int, span_cols: int) -> NoneUpdate the pivot's anchor cell and span.
pivot_set_grand_totalspivot_set_grand_totals(sheet: int, pivot_index: int, rows_enabled: bool, cols_enabled: bool) -> NoneToggle the row / column grand-total bands.
pivot_set_style_infopivot_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) -> NoneSet the pivot's table style and toggles, making the style element present.
pivot_namepivot_name(sheet: int, pivot_index: int) -> strReturn the pivot's name.
pivot_grand_totalspivot_grand_totals(sheet: int, pivot_index: int) -> Tuple[bool, bool]Return (rows, cols), the flags pivot_set_grand_totals writes.
pivot_style_infopivot_style_info(sheet: int, pivot_index: int) -> PivotStyleInfoReturn the table style pivot_set_style_info writes.
pivot_row_field_orderpivot_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_orderpivot_col_field_order(sheet: int, pivot_index: int) -> List[int]Return the column-axis field order.
pivot_field_atpivot_field_at(sheet: int, pivot_index: int, field_idx: int) -> PivotFieldInfoRead the definition of pivot field field_idx.
pivot_field_item_countpivot_field_item_count(sheet: int, pivot_index: int, field_idx: int) -> intReturn the number of items in pivot field field_idx's item list.
pivot_field_item_atpivot_field_item_at(sheet: int, pivot_index: int, field_idx: int, item_idx: int) -> PivotItemInfoRead item item_idx of pivot field field_idx.
pivot_data_field_atpivot_data_field_at(sheet: int, pivot_index: int, data_field_idx: int) -> PivotDataFieldSpecRead data field data_field_idx in the shape pivot_data_field_add accepts.
pivot_field_countpivot_field_count(sheet: int, pivot_index: int) -> intReturn the number of fields configured on the pivot.
pivot_field_addpivot_field_add(sheet: int, pivot_index: int, spec: PivotFieldSpec) -> intPlace a field on the pivot; return its index.
pivot_field_clearpivot_field_clear(sheet: int, pivot_index: int) -> NoneDrop every field from the pivot.
pivot_field_set_axispivot_field_set_axis(sheet: int, pivot_index: int, field_idx: int, axis: Union[PivotAxis, int]) -> NoneSet the axis of pivot field field_idx.
pivot_field_set_sortpivot_field_set_sort(sheet: int, pivot_index: int, field_idx: int, order: Union[PivotSortOrder, int], by_field: str = ...) -> NoneSet the sibling order of pivot field field_idx.
pivot_field_set_subtotal_toppivot_field_set_subtotal_top(sheet: int, pivot_index: int, field_idx: int, top: bool) -> NoneSet the subtotal_top flag on pivot field field_idx.
pivot_field_add_itempivot_field_add_item(sheet: int, pivot_index: int, field_idx: int, name: str, visible: bool) -> NoneAppend a manual-filter item addressed by its label.
pivot_field_add_item_atpivot_field_add_item_at(sheet: int, pivot_index: int, field_idx: int, cache_index: int, visible: bool) -> NoneAppend a manual-filter item addressed by its cache shared-item index.
pivot_field_clear_itemspivot_field_clear_items(sheet: int, pivot_index: int, field_idx: int) -> NoneDrop every manual-filter item from pivot field field_idx.
pivot_field_set_item_visiblepivot_field_set_item_visible(sheet: int, pivot_index: int, field_idx: int, item_idx: int, visible: bool) -> NoneToggle the visibility of item item_idx on field field_idx.
pivot_field_add_subtotal_fnpivot_field_add_subtotal_fn(sheet: int, pivot_index: int, field_idx: int, agg: Union[PivotAggregation, int]) -> NoneAppend a subtotal-fn entry to pivot field field_idx.
pivot_field_clear_subtotal_fnspivot_field_clear_subtotal_fns(sheet: int, pivot_index: int, field_idx: int) -> NoneDrop every subtotal-fn entry from pivot field field_idx.
pivot_field_set_date_grouppivot_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 = ...) -> NoneConfigure date-grouping on pivot field field_idx.
pivot_field_clear_date_grouppivot_field_clear_date_group(sheet: int, pivot_index: int, field_idx: int) -> NoneRemove the date-grouping config from pivot field field_idx.
pivot_field_set_number_formatpivot_field_set_number_format(sheet: int, pivot_index: int, field_idx: int, fmt: str) -> NoneSet the numFmtId of pivot field field_idx.
pivot_set_row_field_orderpivot_set_row_field_order(sheet: int, pivot_index: int, indices: Sequence[int]) -> NoneReplace the row-axis field order with indices.
pivot_set_col_field_orderpivot_set_col_field_order(sheet: int, pivot_index: int, indices: Sequence[int]) -> NoneReplace the column-axis field order with indices.
pivot_data_field_countpivot_data_field_count(sheet: int, pivot_index: int) -> intReturn the number of <dataField> entries on the pivot.
pivot_data_field_addpivot_data_field_add(sheet: int, pivot_index: int, spec: PivotDataFieldSpec) -> intAppend a data-field entry; return its index.
pivot_data_field_setpivot_data_field_set(sheet: int, pivot_index: int, data_field_idx: int, spec: PivotDataFieldSpec) -> NoneReplace the data-field entry at data_field_idx in place.
pivot_data_field_clearpivot_data_field_clear(sheet: int, pivot_index: int) -> NoneDrop every data-field entry from the pivot.
pivot_filter_countpivot_filter_count(sheet: int, pivot_index: int) -> intReturn the number of filters on the pivot; see pivot_filter_at.
pivot_filter_addpivot_filter_add(sheet: int, pivot_index: int, spec: PivotFilterSpec) -> NoneAppend a filter to the pivot; it is saved with it.
pivot_filter_atpivot_filter_at(sheet: int, pivot_index: int, filter_idx: int) -> PivotFilterSpecRead the filter at filter_idx without mutating it.
pivot_filter_clearpivot_filter_clear(sheet: int, pivot_index: int) -> NoneDrop every listed filter from the pivot.
pivot_filter_remove_atpivot_filter_remove_at(sheet: int, pivot_index: int, filter_idx: int) -> NoneRemove the filter at filter_idx.

Pivot caches ​

NameSignatureDescription
pivot_cache_countpivot_cache_count() -> intReturn the number of pivot caches owned by the workbook.
pivot_cache_id_atpivot_cache_id_at(index: int) -> intReturn the cache id at flat index.
pivot_cache_createpivot_cache_create(requested_id: int = ...) -> intCreate a new empty pivot cache; return its assigned id.
get_pivot_cache_worksheet_sourceget_pivot_cache_worksheet_source(cache_id: int) -> Optional[PivotWorksheetSource]Return a cache's worksheet-source metadata, or None when absent.
set_pivot_cache_worksheet_sourceset_pivot_cache_worksheet_source(cache_id: int, source: Optional[PivotWorksheetSource]) -> NoneSet cache worksheet-source metadata; pass None to clear it.
pivot_cache_removepivot_cache_remove(cache_id: int) -> NoneRemove the pivot cache with id cache_id.
pivot_cache_field_countpivot_cache_field_count(cache_id: int) -> intReturn the number of fields on the cache.
pivot_cache_field_namepivot_cache_field_name(cache_id: int, field_idx: int) -> strRead the name of cache field field_idx.
pivot_cache_field_addpivot_cache_field_add(cache_id: int, name: str) -> intAppend a field to the cache; return its index.
pivot_cache_field_clearpivot_cache_field_clear(cache_id: int) -> NoneDrop every field (and record) from the cache.
pivot_cache_field_shared_item_countpivot_cache_field_shared_item_count(cache_id: int, field_idx: int) -> intReturn the shared-item count on cache field field_idx.
pivot_cache_field_add_shared_item_numberpivot_cache_field_add_shared_item_number(cache_id: int, field_idx: int, value: float) -> NoneAppend a numeric shared item to a cache field.
pivot_cache_field_add_shared_item_textpivot_cache_field_add_shared_item_text(cache_id: int, field_idx: int, value: str) -> NoneAppend a text shared item to a cache field.
pivot_cache_field_add_shared_item_boolpivot_cache_field_add_shared_item_bool(cache_id: int, field_idx: int, value: bool) -> NoneAppend a boolean shared item to a cache field.
pivot_cache_field_add_shared_item_blankpivot_cache_field_add_shared_item_blank(cache_id: int, field_idx: int) -> NoneAppend a blank shared item to a cache field.
pivot_cache_field_add_shared_item_errorpivot_cache_field_add_shared_item_error(cache_id: int, field_idx: int, error_code: int) -> NoneAppend an Excel error shared item to a cache field.
pivot_cache_field_clear_shared_itemspivot_cache_field_clear_shared_items(cache_id: int, field_idx: int) -> NoneDrop every shared item from a cache field.
pivot_cache_record_countpivot_cache_record_count(cache_id: int) -> intReturn the number of records on the cache.
pivot_cache_record_addpivot_cache_record_add(cache_id: int) -> intAppend an empty record to the cache; return its index.
pivot_cache_record_clearpivot_cache_record_clear(cache_id: int) -> NoneDrop every record from the cache.
pivot_cache_record_set_numberpivot_cache_record_set_number(cache_id: int, record_idx: int, field_idx: int, value: float) -> NoneSet cache cell (record_idx, field_idx) to a number.
pivot_cache_record_set_textpivot_cache_record_set_text(cache_id: int, record_idx: int, field_idx: int, value: str) -> NoneSet cache cell (record_idx, field_idx) to text.
pivot_cache_record_set_boolpivot_cache_record_set_bool(cache_id: int, record_idx: int, field_idx: int, value: bool) -> NoneSet cache cell (record_idx, field_idx) to a boolean.
pivot_cache_record_set_blankpivot_cache_record_set_blank(cache_id: int, record_idx: int, field_idx: int) -> NoneSet cache cell (record_idx, field_idx) to blank.
pivot_cache_record_set_errorpivot_cache_record_set_error(cache_id: int, record_idx: int, field_idx: int, error_code: int) -> NoneSet cache cell (record_idx, field_idx) to an Excel error.
pivot_cache_idpivot_cache_id(sheet: int, pivot_index: int) -> intReturn 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.

ResultFieldsMeaning
SaveDiagnosticsdowngraded_formula_countFormula cells emitted as cached literals; always zero for XLSX.
deferred_feature_countSheet features not lowered to records; always zero for XLSX.
dropped_part_countPassthrough parts dropped by either writer.
dropped_relationship_countRelationships dropped because their target part was dropped; this can describe the same loss as dropped_part_count.
renumbered_part_countTables emitted under a writer-assigned part id; always zero for XLSB.
ReadDiagnosticsundecoded_formula_countStored formulas that could not be decoded; XLSB only.
undecoded_defined_name_countDefined names skipped because they could not be decoded; XLSB only.
undecoded_part_countXLSB package parts whose content type could not be resolved.
skipped_feature_countOOXML presentation-overlay entries skipped because their references were unusable.
unknown_content_type_countOOXML workbook parts with an unrecognised content type.
python
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:

python
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.

python
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:

python
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)