Skip to content

Workbook API

Version scope

This API reference describes WolfXL 2.1.0.

Constructors

Workbook()

Creates a new workbook in write mode.

load_workbook(filename, read_only=False, data_only=False, keep_links=True, modify=False)

Opens existing workbook.

  • modify=False: read mode
  • modify=True: modify mode (read + patch/save)

  • read_only=True: uses the streaming reader surface for row iteration workflows.

  • data_only=True: returns cached formula values where present.
  • keep_links=True: preserves external-link parts in modify-mode saves.
  • keep_links=False: hides external links when reading and drops external-link parts on modify-mode save.

Conversion

ConversionOptions(destination_format, sheet=None, cell_range=None, values=False, encoding="utf-8", bom=False)

Immutable conversion controls. destination_format accepts xlsx, ods, xlsb, xls, pdf, png, html, txt, csv, or tsv. Static destinations emit one worksheet; sheet=None selects the first worksheet. Structural destinations convert the complete workbook.

CSV and TSV use RFC 4180 quoting and CRLF row terminators. cell_range selects one bounded A1 rectangle. values=False writes formula text, while values=True writes cached formula results. encoding accepts any registered Python codec with explicit byte order for UTF-16/UTF-32; bom=True adds the matching UTF byte-order marker.

Conversion entry points

  • preflight_conversion(source, destination=None, *, destination_format=None, sheet=None, options=None) -> ConversionPreflight
  • convert(source, destination, *, destination_format=None, sheet=None, options=None) -> ConversionReport
  • convert_to_bytes(source, *, destination_format=None, sheet=None, options=None) -> ConversionBytes
  • convert_to_stream(source, destination, *, destination_format=None, sheet=None, options=None) -> ConversionReport

source accepts a path, bytes-like object, or readable binary stream. Destinations may be paths or replacement-safe binary streams that support read(), seek(), tell(), write(), and truncate(). A destination path selects its format by extension unless destination_format or ConversionOptions names it explicitly. Conflicting selectors are rejected before publication.

All routes complete backend generation before publishing. Path destinations use a same-directory temporary file and atomic replacement. Stream routes check every partial write and report a typed SDKIOError if publication stalls or fails. convert_to_bytes() returns an immutable ConversionBytes containing both data and its ConversionReport.

ConversionPreflight and ConversionReport expose ordered preservation and diagnostics tuples. Every discovered feature is classified as preserved, rewritten, or dropped; losses remains the compatibility projection of dropped features. Scanner coverage limits are reported explicitly instead of being treated as proof of lossless conversion.

from wolfxl import ConversionOptions, convert_to_bytes, preflight_conversion

options = ConversionOptions(destination_format="pdf", sheet="Summary")
plan = preflight_conversion("template.xlsx", options=options)
artifact = convert_to_bytes("template.xlsx", options=options)
assert artifact.report.selected_sheets == plan.selected_sheets

PDF and PNG require a render-enabled build. The committed high-value conversion evidence matrix covers these routes:

Source Verified destinations
XLSX XLSX, ODS, XLSB, XLS, PDF, PNG, HTML, TXT, CSV, TSV
ODS XLSX, HTML, TXT, CSV, TSV
XLSB XLSX, XLSB, HTML, TXT, CSV, TSV
XLS XLSX, HTML, TXT, CSV, TSV

The matrix checks public dispatch, deterministic repeated bytes, structural reopenability, output signatures, range/encoding semantics, and explicit feature-loss reporting. Routes outside this matrix may be accepted by a bounded backend but do not carry this matrix-level evidence.

XLSB fidelity ladder

The XLSB writer advances cumulatively. XLSB_FIDELITY_TIERS exposes the same machine-readable table used by the SDK.

Level Boundary Implemented
T0 Blank, number, Boolean, error, and text values Yes
T1 Shared strings, scalar formulas, and cached formula results Yes
T2 Number formats, font name/size, 1904 dates, sheet visibility, and document properties Yes
T3 Merged cells and row/column dimensions No
T4 Hyperlinks, comments, validations, conditional formats, and tables No

T2 is the current rewrite boundary. Higher-tier features remain explicit losses or preflight rejections rather than being silently discarded.

Calculation

CalculationOptions(sheets=(), ranges=(), dirty_only=False, tolerance=1e-10)

Immutable controls for one calculation. sheets filters returned formula cells by worksheet. ranges accepts qualified A1 selections such as "Summary!B2:D20" and filters returned values further. The complete dependency graph is still evaluated before selection. dirty_only=True recalculates from changed input cells when a compatible evaluator cache exists.

workbook.calculator

Returns a CalculationService bound to the workbook:

  • calculate(options=None) -> CalculationReport
  • dependency_graph() -> DependencyGraphSnapshot

CalculationReport.values is an immutable mapping of qualified cell references to computed values. diagnostics records the selected engine, calculation mode, fallback reason, unsupported formulas, cycles, formula counts, and maximum dependency depth. Dirty calculation also returns ordered CellDelta records. Public failures raise CalculationError, which is both an SDKError and a RuntimeError.

DependencyGraphSnapshot

dependency_graph() returns an immutable, deterministically ordered snapshot of the workbook formula graph. Inspecting it never mutates workbook or dirty state.

Member Purpose
formulas Sorted (cell, formula) pairs for every formula cell
dependencies Sorted forward edges, (formula cell, precedent cells)
dependents Sorted reverse edges, (precedent cell, formula cells)
topological_order Calculation order; empty when a cycle is reported
cycles Circular-reference messages naming the involved cells
precedents_of(cell) Direct precedents of one formula cell
dependents_of(cell) Direct formula dependents of any cell
affected_cells(changed) Transitively dirty formulas in calculation order

Edges are complete rather than range endpoints: a range precedent contributes every cell it covers, across sheets, so an interior edit still propagates. References are canonicalized to the workbook's own worksheet spelling, so case variants and quoted sheet tokens such as 'O''Brien Data'!A1:A2 resolve to one identity. A formula whose cumulative unique precedents exceed 100000 cells raises CalculationError before any edge is materialized.

snapshot = workbook.calculator.dependency_graph()
snapshot.precedents_of("Summary!C1")
snapshot.affected_cells(("Input Data!A2",))

The compatibility methods Workbook.calculate() and Workbook.recalculate(perturbations, tolerance) remain available.

from wolfxl import CalculationOptions, load_workbook

workbook = load_workbook("model.xlsx", modify=True)
report = workbook.calculator.calculate(
    CalculationOptions(sheets=("Summary",), dirty_only=True)
)
print(report.values, report.diagnostics.engine)

Rendering

RenderOptions(...)

RenderOptions selects exactly one workbook, sheet, range, paginated-sheet, or chart target. Its public fields are:

Field Purpose
format png or pdf; chart selection also accepts jpeg and svg
sheet Worksheet title or object; None selects the workbook route
cell_range One A1 rectangle
chart_index Zero-based native chart order
paginated Print-aware multi-page PDF route
output None for returned bytes, or a path/binary stream
dpi, scale Positive output controls
background Optional RGB color such as #FFFFFF
width, height Optional chart-only pixel dimensions

workbook.renderer

workbook.renderer.render(options=None) -> RenderReport routes through the same native renderer used by the direct methods. RenderReport.result contains bytes, an immutable sheet-to-bytes mapping, or None after path/stream publication. RenderDiagnostics records the selected route, format, rendered sheet count, typed diagnostics, and any omitted or substituted visual features.

Direct workbook methods remain available:

  • render_workbook_to_pdf(...)
  • render_sheet_to_png(...), render_sheet_to_pdf(...)
  • render_sheet_to_paginated_pdf(...)
  • render_range_to_png(...), render_range_to_pdf(...)
  • render_chart_to_png(...), render_chart_to_pdf(...)
  • render_chart_to_jpeg(...), render_chart_to_svg(...)

JPEG output is genuine JPEG and SVG output is vector/text SVG. Chart width or height alone preserves aspect ratio subject to integer-pixel rounding; passing both sets the exact canvas size.

from wolfxl import RenderOptions, load_workbook

workbook = load_workbook("dashboard.xlsx")
report = workbook.renderer.render(
    RenderOptions(format="svg", sheet="Summary", chart_index=0, width=1200)
)
svg_bytes = report.result

Inspection, capabilities, and binary I/O

Standalone inspection and loading

  • inspect_workbook(source) -> WorkbookPreflight
  • load_workbook_from_bytes(data, ...) -> Workbook
  • load_workbook_from_stream(stream, ...) -> Workbook

inspect_workbook() accepts a path, bytes-like object, or readable binary stream. It returns source format, package parts, preservation inventory, diagnostics, and operation capability results without mutating a workbook. Seekable streams are scanned from offset zero and restored to their original position.

Workbook capability and save methods

  • workbook.preflight_save(destination_format="xlsx") -> CapabilityResult
  • workbook.capability(operation, destination_format=None) -> CapabilityResult
  • workbook.save_to_bytes(*, destination_format="xlsx", password=None) -> bytes
  • workbook.save_to_stream(stream, *, destination_format="xlsx", password=None) -> None

Capability results use supported, supported_with_warnings, unsupported, or unknown tiers and carry typed diagnostics plus preservation records. Queries do not flush pending writes or publish artifacts. Explicit byte and stream saves accept only destination_format="xlsx" and reject other formats before publication. save_to_stream() destinations must support read(), seek(), tell(), write(), and truncate() so failed replacement can restore existing bytes and position. Legacy Workbook.save(binary_stream) also accepts forward-only binary sinks, preserving its established compatibility. After a failed write-only workbook publication, WolfXL retains the completed artifact for a same-options retry, but a forward-only sink cannot roll back bytes it already accepted before a write or flush failure.

Shared diagnostics

Calculation, rendering, conversion, inspection, and save operations share these root exports:

  • SDKDiagnostic, DiagnosticCode, DiagnosticSeverity, DiagnosticContext
  • SDKError, SDKIOError, InvalidSDKRequestError, UnsupportedSDKOperationError
  • SDKWarning, SDKRuntimeWarning, SDKDeprecationWarning
  • CapabilityResult, SupportTier
  • PreservationRecord, PreservationDisposition, WorkbookPreflight
  • CancellationToken, OperationProgress, ProgressCallback, OperationCancelledError

Diagnostics and reports expose deterministic to_dict() payloads. Context uses normalized package-part and A1 fields rather than host filesystem paths.

Long-operation control and concurrency

CalculationOptions, RenderOptions, and ConversionOptions accept:

  • cancellation_token: CancellationToken | None
  • progress: ProgressCallback | None

OperationProgress reports a stable operation name, phase, completed count, and optional total. CancellationToken.cancel() is thread-safe and monotonic. Cancellation raises OperationCancelledError, which is also an SDKError and RuntimeError, with diagnostic code operation_cancelled.

Cancellation is cooperative at Python-owned service checkpoints. A request cancelled before dispatch does not call the evaluator, renderer, or converter. Once a monolithic native method has started, it runs to its next service checkpoint; the current API does not promise per-formula, per-page, or mid-conversion interruption. Direct legacy methods such as Workbook.calculate(), Workbook.save(), and Workbook.render_sheet_to_png() do not accept these controls.

A mutable Workbook and its worksheets belong to one thread. Create, use, and close a workbook on that owner thread; do not share one workbook across worker threads. Independent workbooks are supported in parallel. close() releases thread-affine native calculation, reader, writer, and patcher handles on the calling thread.

Scale boundaries

Workbook(write_only=True) streams row XML into a per-sheet spool. Each active sheet retains up to 512 KiB of row XML in memory, then rolls to an unnamed OS temporary file that is removed when its final handle closes. Shared strings and styles remain resident, so workloads with many unique strings or styles are not constant-memory. Write-only workbooks are append-only and consumed after a successful save.

load_workbook(..., read_only=True) streams worksheet rows. Normal eager loads, calculation, rendering, conversion, images, shared strings, and style tables are not covered by a bounded-memory guarantee. Worksheet coordinates are limited to 1,048,576 rows and 16,384 columns; out-of-range writes fail instead of silently truncating.

Properties

  • sheetnames -> list[str]
  • active -> Worksheet | None
  • power_queries -> PowerQueryCollection

Methods

  • create_sheet(title: str) -> Worksheet (write mode)
  • save(filename: str) -> None
  • close() -> None
  • __getitem__(name: str) -> Worksheet
  • add_power_query(name: str, formula: str) -> PowerQueryDefinition (modify mode)
  • update_power_query(name: str, formula: str) -> PowerQueryDefinition (modify mode)
  • remove_power_query(name: str) -> PowerQueryDefinition (modify mode)
  • execute_power_query(name: str | None = None) -> None (always raises NotImplementedError)

Power Query

WolfXL inspects embedded, connection-only Power Query definitions without executing connectors or accessing data sources. Inventory records expose names, connector kinds, load destinations, formula sizes, and formula hashes. They do not expose formulas, locations, credentials, or raw DataMashup bytes.

Path-backed workbooks opened with modify=True can add, update, and remove bounded definitions:

from wolfxl import load_workbook

workbook = load_workbook("template.xlsx", modify=True)
workbook.update_power_query("Sales", "let Value = 1 in Value")
workbook.save("updated.xlsx")

Authoring accepts a restricted, offline subset of M. It rejects connector calls, dynamic evaluation, credential-like tokens, source locations, worksheet loads, data-model loads, and native queries before writing output. WolfXL preserves unrelated package parts and validates the source package again during save.

Context manager

Workbook supports with statements.