Auto-Generated Reference¶
This page renders the full public API from source docstrings via mkdocstrings.
All symbols are importable from the top-level ezxl package.
Exceptions¶
EzXlError
¶
Bases: Exception
Base exception for all EzXl errors.
All exceptions raised by the EzXl library inherit from this class.
Catching EzXlError is sufficient to handle any EzXl-originated
failure without importing subclasses.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Example
try: ... raise EzXlError("something went wrong") ... except EzXlError as e: ... print(e) something went wrong
Source code in src/ezxl/exceptions.py
options: show_source: false
ExcelNotAvailableError
¶
Bases: EzXlError
Raised when Excel is not open or the COM server is unreachable.
Typically thrown when win32com.client.Dispatch or
win32com.client.GetActiveObject fails because no Excel process is
running, or because the COM registration is broken.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Example
raise ExcelNotAvailableError( ... "No running Excel instance found", cause=original_err ... )
Source code in src/ezxl/exceptions.py
options: show_source: false
ExcelSessionLostError
¶
Bases: EzXlError
Raised when an established COM connection is lost mid-operation.
This can happen when the user closes Excel while an automation session
is active, or when Excel crashes. Unlike ExcelNotAvailableError,
this implies a previously valid connection existed.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Source code in src/ezxl/exceptions.py
options: show_source: false
ExcelThreadViolationError
¶
Bases: EzXlError
Raised when a COM call is attempted from the wrong thread.
Excel COM operates under the Single-Threaded Apartment (STA) model.
All COM calls must originate from the thread that created the
ExcelApp instance. This exception is raised proactively before
the COM call reaches the dispatcher to give a clear diagnostic.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Source code in src/ezxl/exceptions.py
options: show_source: false
WorkbookNotFoundError
¶
Bases: EzXlError
Raised when a workbook cannot be found by name in the Excel session.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Example
raise WorkbookNotFoundError("No workbook named 'report.xlsx'")
Source code in src/ezxl/exceptions.py
options: show_source: false
SheetNotFoundError
¶
Bases: EzXlError
Raised when a worksheet cannot be found by name in a workbook.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Example
raise SheetNotFoundError("No sheet named 'Summary' in 'report.xlsx'")
Source code in src/ezxl/exceptions.py
options: show_source: false
COMOperationError
¶
Bases: EzXlError
Raised for unclassified COM errors that do not map to a specific subclass.
This is the catch-all wrapper for pywintypes.com_error exceptions.
If a COM error can be identified as a lost session or unavailability
issue, the more specific subclass should be used instead.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Source code in src/ezxl/exceptions.py
options: show_source: false
GUIOperationError
¶
Bases: EzXlError
Raised when a GUI-level COM operation fails for ribbon, menu, or dialog.
Distinct from COMOperationError to allow consumer code to
differentiate between generic COM failures and failures that occur
specifically within GUI interaction surfaces (ribbon, CommandBars,
file dialogs, message boxes).
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Example
raise GUIOperationError( ... "Failed to execute ribbon command 'FileSave'", cause=exc ... )
Source code in src/ezxl/exceptions.py
options: show_source: false
FormatterError
¶
Bases: EzXlError
Raised when an openpyxl-based formatting operation fails.
This exception covers errors that occur during closed-file formatting
via ExcelFormatter, such as invalid cell references, unsupported
style properties, or file I/O failures.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable description of the error.
TYPE:
|
cause
|
Original exception that triggered this error, if any.
TYPE:
|
Source code in src/ezxl/exceptions.py
options: show_source: false
COM automation¶
ExcelApp
¶
COM automation session for a single Excel Application instance.
Provides a unified interface for opening, navigating, and controlling Excel via COM, regardless of whether the Application object was dispatched (new process) or attached (existing process).
Threading
This class is not thread-safe. Excel COM uses the STA model.
All method calls must originate from the thread that constructed
the instance. Calls from other threads raise
ExcelThreadViolationError immediately.
Lifecycle¶
Two usage patterns are supported:
Context manager (recommended for short, bounded sessions) — cleanup is automatic on exit::
with ExcelApp(mode="dispatch", visible=False) as xl:
wb = xl.open("C:/reports/budget.xlsx")
wb.save()
# Excel quit automatically
Manual lifecycle (long-running sessions, e.g. consumer libraries) —
call :meth:quit explicitly when done. In attach mode, quit
is optional; Excel stays running and the Python reference is released::
xl = ExcelApp(mode="attach")
wb = xl.open("C:/reports/budget.xlsx")
# ... many operations spread across multiple calls ...
xl.quit() # optional in attach mode — Excel stays running
The COM object is resolved lazily on the first public method call;
constructing an ExcelApp instance does not connect to COM.
| PARAMETER | DESCRIPTION |
|---|---|
mode
|
TYPE:
|
visible
|
Whether to make the Excel window visible. Only relevant
in
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelNotAvailableError
|
If |
Source code in src/ezxl/core/_excel_app.py
gui
property
¶
gui: GUIProxy
Access GUI interaction helpers (ribbon, menus, dialogs, keys).
Returns a GUIProxy that bundles all GUI automation surfaces.
The proxy is created fresh on each access; it holds no state of
its own beyond a reference to this ExcelApp instance.
Surfaces available via the proxy:
gui.ribbon— MSO ribbon execution and state queries.gui.menu— Legacy CommandBar traversal and execution.gui.dialog— File-open, file-save, and alert dialogs.gui.send_keys(…)—Application.SendKeyspass-through.
| RETURNS | DESCRIPTION |
|---|---|
GUIProxy
|
Facade bound to this
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If accessed from the wrong thread. |
Example
with ExcelApp(mode="attach") as xl: ... xl.gui.ribbon.execute("FileSave") ... path = xl.gui.dialog.get_file_open()
hwnd
property
¶
Win32 window handle of this Excel Application instance.
Returns the Application.Hwnd COM property. Used to bind
pywinauto backends to the exact same Excel window managed by
this ExcelApp session, preventing cross-instance interference
when multiple Excel processes are running simultaneously.
| RETURNS | DESCRIPTION |
|---|---|
int
|
The Win32 HWND of the Excel main window.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If the COM call fails. |
Example
hwnd = xl.hwnd gui = GUIProxy(xl, keys=PywinautoKeysBackend(hwnd=hwnd))
open
¶
open(path: str | Path) -> WorkbookProxy
Open a workbook file and return a proxy for it.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
Absolute path to the workbook file.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
WorkbookProxy
|
A proxy bound to the opened workbook.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If Excel cannot open the file. |
Example
wb = xl.open("C:/data/report.xlsx")
Source code in src/ezxl/core/_excel_app.py
workbook
¶
workbook(name: str | None = None) -> WorkbookProxy
Return a proxy for an already-open workbook.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The workbook name as displayed in Excel's title bar
(e.g.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
WorkbookProxy
|
A proxy bound to the named workbook.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If no workbook with that name is open. |
COMOperationError
|
If the COM call fails. |
Example
wb = xl.workbook("report.xlsx")
Source code in src/ezxl/core/_excel_app.py
run_macro
¶
Execute a VBA macro by name with optional arguments.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Fully qualified macro name (e.g.
TYPE:
|
*args
|
Positional arguments forwarded to the macro.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Any
|
The return value of the macro, if any.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If the macro call fails. |
Example
xl.run_macro("Module1.FormatSheet", "Sheet1")
Source code in src/ezxl/core/_excel_app.py
execute_ribbon
¶
Execute a built-in ribbon command by its MSO identifier.
Uses Application.CommandBars.ExecuteMso to trigger any built-in
Excel ribbon button programmatically without navigating a menu tree.
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
The MSO control identifier string
(e.g.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If the MSO ID is unknown or execution fails. |
Example
xl.execute_ribbon("FileSave")
Source code in src/ezxl/core/_excel_app.py
wait_ready
¶
Block until Excel reports it is ready.
Delegates to _com_utils.wait_until_ready. Useful after
operations that trigger asynchronous recalculation or file I/O.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Maximum seconds to wait. Defaults to 30.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If the timeout is exceeded. |
Example
xl.wait_ready(timeout=60.0)
Source code in src/ezxl/core/_excel_app.py
quit
¶
Quit the Excel Application.
This method is safe to call multiple times; subsequent calls after the first are no-ops.
| PARAMETER | DESCRIPTION |
|---|---|
save_changes
|
If
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If the quit call fails unexpectedly. |
Example
xl.quit(save_changes=False)
Source code in src/ezxl/core/_excel_app.py
options: show_source: false members: - init - enter - exit - open - workbook - run_macro - execute_ribbon - wait_ready - quit - gui - hwnd
WorkbookProxy
¶
WorkbookProxy(app: ExcelApp, name: str)
COM proxy for a single Excel Workbook.
Instances are created by ExcelApp.open() or ExcelApp.workbook().
Do not instantiate directly.
All methods enforce COM thread safety by delegating to the parent
ExcelApp's thread identity.
| PARAMETER | DESCRIPTION |
|---|---|
app
|
The
TYPE:
|
name
|
The workbook name as shown in Excel's title bar
(e.g.
TYPE:
|
Example
with ExcelApp() as xl: ... wb = xl.open("C:/data/report.xlsx") ... print(wb.name) ... wb.save() ... wb.close()
Source code in src/ezxl/core/_workbook.py
name
property
¶
The workbook filename as shown in Excel's title bar.
| RETURNS | DESCRIPTION |
|---|---|
str
|
Workbook name (e.g.
TYPE:
|
sheets
property
¶
List of all worksheet names in this workbook.
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
list[str]: Sheet names in tab order. |
| RAISES | DESCRIPTION |
|---|---|
WorkbookNotFoundError
|
If the workbook is no longer open. |
sheet
¶
sheet(name: str) -> SheetProxy
Return a proxy for a named worksheet.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The worksheet name (case-sensitive, as shown on the tab).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
SheetProxy
|
A proxy bound to the named worksheet.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
SheetNotFoundError
|
If no sheet with that name exists. |
WorkbookNotFoundError
|
If the workbook is no longer open. |
Example
ws = wb.sheet("Summary")
Source code in src/ezxl/core/_workbook.py
save
¶
Save the workbook in place (equivalent to Ctrl+S).
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If the workbook is no longer open. |
COMOperationError
|
If the save fails. |
Example
wb.save()
Source code in src/ezxl/core/_workbook.py
save_as
¶
Save the workbook to a new path, optionally changing its format.
Uses COM Workbook.SaveAs which keeps Excel open. Suitable for
format conversion (e.g. xlsx → csv) via an active Excel session.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
Destination file path. The extension determines the format
when
TYPE:
|
fmt
|
Explicit format override. Must be a key from the internal
format map (e.g.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If the workbook is no longer open. |
COMOperationError
|
If SaveAs fails. |
ValueError
|
If the file extension cannot be mapped to a COM format. |
Example
wb.save_as("C:/output/report.csv") wb.save_as("C:/output/report_backup.xlsx", fmt=".xlsx")
Source code in src/ezxl/core/_workbook.py
close
¶
Close the workbook.
| PARAMETER | DESCRIPTION |
|---|---|
save
|
If
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If the workbook is no longer open. |
COMOperationError
|
If the close operation fails. |
Example
wb.close(save=True)
Source code in src/ezxl/core/_workbook.py
options: show_source: false members: - name - sheets - sheet - save - save_as - close
SheetProxy
¶
SheetProxy(workbook: WorkbookProxy, name: str)
COM proxy for a single Excel Worksheet.
Instances are created by WorkbookProxy.sheet(). Do not instantiate
directly.
| PARAMETER | DESCRIPTION |
|---|---|
workbook
|
The parent
TYPE:
|
name
|
The worksheet name (as shown on the tab).
TYPE:
|
Example
ws = wb.sheet("Data") ws.cell("A1").value = "Hello" ws.calculate()
Source code in src/ezxl/core/_sheet.py
name
property
¶
The worksheet name as shown on the tab.
| RETURNS | DESCRIPTION |
|---|---|
str
|
Sheet name.
TYPE:
|
used_range
property
¶
used_range: RangeProxy
The smallest rectangle that contains all used cells.
| RETURNS | DESCRIPTION |
|---|---|
RangeProxy
|
Proxy over the
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
SheetNotFoundError
|
If the sheet is no longer available. |
cell
¶
cell(ref: str) -> CellProxy
Return a proxy for a single cell.
| PARAMETER | DESCRIPTION |
|---|---|
ref
|
Cell address in A1 notation (e.g.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
CellProxy
|
A proxy bound to the cell.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
SheetNotFoundError
|
If the sheet is no longer available. |
Example
ws.cell("A1").value = 42
Source code in src/ezxl/core/_sheet.py
range
¶
range(ref: str) -> RangeProxy
Return a proxy for a cell range.
| PARAMETER | DESCRIPTION |
|---|---|
ref
|
Range address in A1 notation (e.g.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
RangeProxy
|
A proxy bound to the range.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
SheetNotFoundError
|
If the sheet is no longer available. |
Example
rng = ws.range("A1:C5") data = rng.values
Source code in src/ezxl/core/_sheet.py
calculate
¶
Trigger recalculation of all formulas on this sheet.
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
SheetNotFoundError
|
If the sheet is no longer available. |
Example
ws.calculate()
Source code in src/ezxl/core/_sheet.py
options: show_source: false members: - name - used_range - cell - range - calculate
CellProxy
¶
CellProxy(sheet: SheetProxy, ref: str)
COM proxy for a single cell in a worksheet.
Instances are created by SheetProxy.cell(). Do not instantiate
directly.
| PARAMETER | DESCRIPTION |
|---|---|
sheet
|
The parent
TYPE:
|
ref
|
Cell address in A1 notation (e.g.
TYPE:
|
Example
cell = ws.cell("C7") cell.value = 100 print(cell.formula) 100
Source code in src/ezxl/core/_sheet.py
address
property
¶
The absolute address of this cell (e.g. "$B$3").
| RETURNS | DESCRIPTION |
|---|---|
str
|
Cell address in absolute notation.
TYPE:
|
value
property
writable
¶
The cell's current value, normalised to a Python type.
COM date objects are converted to datetime. Error values
(#N/A etc.) are returned as None with a WARNING log.
| RETURNS | DESCRIPTION |
|---|---|
Any
|
The cell value, or
TYPE:
|
formula
property
writable
¶
The formula string in the cell (e.g. "=SUM(A1:A5)").
Returns an empty string for cells with no formula.
| RETURNS | DESCRIPTION |
|---|---|
str
|
Formula string, or empty string if none.
TYPE:
|
options: show_source: false members: - address - value - formula
RangeProxy
¶
RangeProxy(sheet: SheetProxy, ref: str)
COM proxy for a rectangular range of cells in a worksheet.
Instances are created by SheetProxy.range() or accessed via
SheetProxy.used_range. Do not instantiate directly.
| PARAMETER | DESCRIPTION |
|---|---|
sheet
|
The parent
TYPE:
|
ref
|
Range address in A1 notation (e.g.
TYPE:
|
Example
rng = ws.range("A1:C3") data = rng.values # list[list[Any]] rng.values = [[1, 2, 3], ... [4, 5, 6], ... [7, 8, 9]]
Source code in src/ezxl/core/_sheet.py
address
property
¶
The address of this range (e.g. "A1:D10").
| RETURNS | DESCRIPTION |
|---|---|
str
|
Range address.
TYPE:
|
values
property
writable
¶
All cell values in the range as a list of rows.
Single-row or single-column ranges are normalised to a 2D
list-of-lists for a consistent return type. COM dates are converted
to datetime; error cells return None.
| RETURNS | DESCRIPTION |
|---|---|
list[list[Any]]
|
list[list[Any]]: Row-major 2D list of cell values. |
Example
data = ws.range("A1:C3").values data[0][] # row 1, col A
options: show_source: false members: - address - values
GUI interaction¶
GUIProxy
¶
GUIProxy(app: ExcelApp, ribbon: AbstractRibbonBackend | None = None, menu: AbstractMenuBackend | None = None, dialog: AbstractDialogBackend | None = None, keys: AbstractKeysBackend | None = None, backstage: AbstractBackstageFileOps | None = None, backstage_nav: AbstractBackstageNavigator | None = None)
Unified facade for GUI-level Excel interaction.
Instantiated by ExcelApp.gui and bundles all six automation
surfaces (ribbon, menu, dialog, keys, backstage, backstage_nav)
under a single object.
Backend injection¶
Each surface can be replaced at construction time by passing an
alternative implementation that satisfies the corresponding abstract
protocol. This is the primary extension point for non-COM backends
such as pywinauto. Passing None (the default) selects the
standard COM implementation for that surface — except for
backstage_nav, which defaults to None (no UIA navigator).
The backstage and backstage_nav surfaces are intentionally
separate:
backstage(AbstractBackstageFileOps) — file I/O operations via COM. Focus-independent, locale-independent. Always present.backstage_nav(AbstractBackstageNavigator | None) — visual panel navigation via UIA. Required foropen_optionsandopen_save_as_panel. Inject explicitly when needed.
| PARAMETER | DESCRIPTION |
|---|---|
app
|
The active
TYPE:
|
ribbon
|
Optional ribbon backend. Defaults to
:class:
TYPE:
|
menu
|
Optional menu backend. Defaults to
:class:
TYPE:
|
dialog
|
Optional dialog backend. Defaults to
:class:
TYPE:
|
keys
|
Optional keys backend. Defaults to
:class:
TYPE:
|
backstage
|
Optional Backstage file-ops backend. Defaults to
:class:
TYPE:
|
backstage_nav
|
Optional Backstage UIA navigator. Defaults to
TYPE:
|
Security note
When injecting pywinauto backends, always pass hwnd=app.hwnd
to bind the backend to the exact Excel window managed by this
session. Omitting hwnd causes pywinauto to attach to the
first Excel window it finds, which may not be the correct one
when multiple Excel instances are running.
Example
with ExcelApp(mode="attach") as xl: ... xl.gui.ribbon.execute("FileSave") ... xl.gui.backstage.save() ... path = xl.gui.dialog.get_file_open() ... xl.gui.send_keys("^{HOME}")
Example — with UIA navigator::
gui = GUIProxy(
xl,
backstage=COMBackstageBackend(xl),
backstage_nav=PywinautoBackstageBackend(hwnd=xl.hwnd, locale="fr"),
)
gui.backstage.save() # COM: direct save
gui.backstage.save_as(path="out.xlsx") # COM: format-aware save
gui.backstage_nav.open_options() # UIA: opens Options panel
gui.backstage_nav.open_save_as_panel() # UIA: opens panel only
Source code in src/ezxl/gui/_gui_proxy.py
ribbon
property
¶
ribbon: AbstractRibbonBackend
Return the ribbon backend for MSO ribbon command interaction.
| RETURNS | DESCRIPTION |
|---|---|
AbstractRibbonBackend
|
The configured ribbon backend
(default: :class:
TYPE:
|
Example
xl.gui.ribbon.execute("FileSave") xl.gui.ribbon.is_enabled("Copy") True
menu
property
¶
menu: AbstractMenuBackend
Return the menu backend for legacy CommandBar interaction.
| RETURNS | DESCRIPTION |
|---|---|
AbstractMenuBackend
|
The configured menu backend
(default: :class:
TYPE:
|
Example
xl.gui.menu.list_bars() ['Standard', 'Formatting', ...]
dialog
property
¶
dialog: AbstractDialogBackend
Return the dialog backend for file picker and alert dialogs.
| RETURNS | DESCRIPTION |
|---|---|
AbstractDialogBackend
|
The configured dialog backend
(default: :class:
TYPE:
|
Example
path = xl.gui.dialog.get_file_open(title="Select report")
backstage
property
¶
backstage: AbstractBackstageFileOps
Return the Backstage file-ops backend.
Handles save, save_as, open_file, and
close_workbook via the COM object model — focus-independent
and locale-independent.
The default backend is
:class:~ezxl.gui.win32com._backstage.COMBackstageBackend.
Replace it at construction time to swap the implementation::
gui = GUIProxy(xl, backstage=MyCustomFileOpsBackend(xl))
| RETURNS | DESCRIPTION |
|---|---|
AbstractBackstageFileOps
|
The configured file-ops backend.
TYPE:
|
Example
xl.gui.backstage.save() xl.gui.backstage.save_as(path="C:\output.xlsx")
backstage_nav
property
¶
backstage_nav: AbstractBackstageNavigator | None
Return the Backstage UIA navigator, or None if not injected.
Handles open_options, open_save_as_panel, open_file,
and close_workbook via UIA direct click. This backend must be
injected explicitly — there is no COM default::
gui = GUIProxy(
xl,
backstage_nav=PywinautoBackstageBackend(
hwnd=xl.hwnd, locale="fr"
),
)
| RETURNS | DESCRIPTION |
|---|---|
AbstractBackstageNavigator | None
|
AbstractBackstageNavigator | None: The configured UIA navigator,
or |
Example
if xl.gui.backstage_nav is not None: ... xl.gui.backstage_nav.open_options()
send_keys
¶
Send a keystroke sequence to the Excel Application window.
Delegates to the configured :class:~ezxl.gui._protocols.AbstractKeysBackend.
The keys string must use standard VBA SendKeys notation
(e.g. "{ENTER}", "^s" for Ctrl+S).
| PARAMETER | DESCRIPTION |
|---|---|
keys
|
Keystroke string in VBA SendKeys notation.
TYPE:
|
wait
|
If
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If the SendKeys call fails. |
Example
xl.gui.send_keys("^s") # Ctrl+S xl.gui.send_keys("{ESCAPE}")
Source code in src/ezxl/gui/_gui_proxy.py
options: show_source: false members: - init - ribbon - menu - dialog - backstage - backstage_nav - send_keys
GUI protocols (ABCs)¶
AbstractRibbonBackend
¶
Bases: ABC
Contract for ribbon command execution and state queries.
Any class that implements this interface can be injected into
:class:~ezxl.gui.GUIProxy as the ribbon backend, replacing the
default COM-based implementation.
Implementations are responsible for thread-safety; the caller
(:class:~ezxl.gui.GUIProxy) does not perform additional
thread checks.
execute
abstractmethod
¶
Execute a built-in ribbon command by its MSO identifier.
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
MSO control identifier string
(e.g.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the MSO ID is unknown or the command cannot be executed in the current application state. |
Source code in src/ezxl/gui/_protocols.py
is_enabled
abstractmethod
¶
Return whether a ribbon command is currently enabled.
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
MSO control identifier string.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the MSO ID is unknown or the query fails. |
Source code in src/ezxl/gui/_protocols.py
is_pressed
abstractmethod
¶
Return whether a ribbon toggle command is currently pressed.
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
MSO control identifier string.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
Source code in src/ezxl/gui/_protocols.py
is_visible
abstractmethod
¶
Return whether a ribbon command is currently visible.
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
MSO control identifier string.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the MSO ID is unknown or the query fails. |
Source code in src/ezxl/gui/_protocols.py
options: show_source: false members: - execute - is_enabled - is_pressed - is_visible
AbstractMenuBackend
¶
Bases: ABC
Contract for legacy CommandBar traversal and control execution.
Any class that implements this interface can be injected into
:class:~ezxl.gui.GUIProxy as the menu backend, replacing the
default COM-based implementation.
click
abstractmethod
¶
Traverse a CommandBar by caption path and execute the final control.
| PARAMETER | DESCRIPTION |
|---|---|
bar_name
|
The name of the CommandBar to start from.
TYPE:
|
*item_path
|
One or more control captions forming the path to the target control. At least one caption is required.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the bar, any intermediate control, or the final control cannot be found, or if execution fails. |
Source code in src/ezxl/gui/_protocols.py
list_bars
abstractmethod
¶
Return the names of all CommandBars registered with Excel.
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
list[str]: Sorted list of CommandBar names. |
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the COM collection cannot be iterated. |
Source code in src/ezxl/gui/_protocols.py
list_controls
abstractmethod
¶
Return the captions of all top-level controls in a CommandBar.
| PARAMETER | DESCRIPTION |
|---|---|
bar_name
|
The name of the CommandBar to inspect.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
list[str]: Captions of the bar's top-level controls, in order. |
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the bar cannot be found or the controls collection cannot be iterated. |
Source code in src/ezxl/gui/_protocols.py
options: show_source: false members: - click - list_bars - list_controls
AbstractDialogBackend
¶
Bases: ABC
Contract for file-open, file-save, and message-box dialogs.
Any class that implements this interface can be injected into
:class:~ezxl.gui.GUIProxy as the dialog backend, replacing the
default COM/Win32-based implementation.
Default parameter values in implementing methods must match those
declared on :class:~ezxl.gui.DialogProxy.
get_file_open
abstractmethod
¶
get_file_open(title: str = 'Open', initial_dir: str | None = None, filter: str = 'Excel Files (*.xls*), *.xls*') -> str | None
Show a file-open picker dialog and return the selected path.
| PARAMETER | DESCRIPTION |
|---|---|
title
|
Dialog title bar text. Defaults to
TYPE:
|
initial_dir
|
Directory to open the dialog in. If
TYPE:
|
filter
|
File-type filter string. Defaults to Excel files.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
str | None: Absolute path chosen by the user, or |
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the underlying call fails. |
Source code in src/ezxl/gui/_protocols.py
get_file_save
abstractmethod
¶
get_file_save(title: str = 'Save As', initial_dir: str | None = None, filter: str = 'Excel Files (*.xlsx), *.xlsx') -> str | None
Show a file-save picker dialog and return the selected path.
| PARAMETER | DESCRIPTION |
|---|---|
title
|
Dialog title bar text. Defaults to
TYPE:
|
initial_dir
|
Directory to open the dialog in. If
TYPE:
|
filter
|
File-type filter string. Defaults to
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
str | None: Absolute path chosen by the user, or |
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the underlying call fails. |
Source code in src/ezxl/gui/_protocols.py
alert
abstractmethod
¶
Display a modal information message box.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
The body text displayed in the message box.
TYPE:
|
title
|
Caption for the message box title bar.
Defaults to
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the underlying call fails. |
Source code in src/ezxl/gui/_protocols.py
options: show_source: false members: - get_file_open - get_file_save - alert
AbstractKeysBackend
¶
Bases: ABC
Contract for keystroke injection into Excel.
Any class that implements this interface can be injected into
:class:~ezxl.gui.GUIProxy as the keys backend, replacing the
default COM-based implementation.
send_keys
abstractmethod
¶
Send a keystroke sequence to the Excel Application window.
| PARAMETER | DESCRIPTION |
|---|---|
keys
|
Keystroke string in VBA SendKeys notation
(e.g.
TYPE:
|
wait
|
If
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If the keystroke injection call fails. |
Source code in src/ezxl/gui/_protocols.py
options: show_source: false members: - send_keys
AbstractBackstageFileOps
¶
Bases: ABC
Contract for Excel Backstage file operations via COM.
Covers the four operations that the COM object model executes
reliably, focus-independently, and locale-independently:
save, save_as, open_file, and close_workbook.
This contract is implemented by
:class:~ezxl.gui.win32com.COMBackstageBackend. Inject it into
:class:~ezxl.gui.GUIProxy via the backstage parameter::
gui = GUIProxy(xl, backstage=COMBackstageBackend(xl))
save
abstractmethod
¶
Save the active workbook.
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If no workbook is currently open. |
GUIOperationError
|
If the action cannot be completed. |
Source code in src/ezxl/gui/_protocols.py
save_as
abstractmethod
¶
Save the active workbook under a new path, or open the Save As dialog.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
Absolute path for the new file, including extension.
If
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If no workbook is currently open. |
GUIOperationError
|
If the panel cannot be opened or path entry fails. |
Source code in src/ezxl/gui/_protocols.py
open_file
abstractmethod
¶
Show the built-in Excel Open dialog.
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the dialog cannot be opened. |
close_workbook
abstractmethod
¶
Close the active workbook without saving.
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If no workbook is currently open. |
GUIOperationError
|
If the action cannot be completed. |
Source code in src/ezxl/gui/_protocols.py
options: show_source: false members: - save - save_as - open_file - close_workbook
AbstractBackstageNavigator
¶
Bases: ABC
Contract for Excel Backstage visual navigation via UI Automation.
Covers operations that require UIA-level interaction with the Backstage overlay: navigating to the Options panel, opening the Save As panel without confirming, and UIA-driven open/close actions.
This contract is implemented by
:class:~ezxl.gui.pywinauto.PywinautoBackstageBackend. Inject it
into :class:~ezxl.gui.GUIProxy via the backstage_nav parameter::
gui = GUIProxy(
xl,
backstage=COMBackstageBackend(xl),
backstage_nav=PywinautoBackstageBackend(hwnd=xl.hwnd, locale="fr"),
)
Note
backstage_nav is optional — :class:~ezxl.gui.GUIProxy defaults
it to None. Access it via xl.gui.backstage_nav; guard with
an is not None check before calling if it may be absent.
open_options
abstractmethod
¶
Navigate to the Excel Options panel via the Backstage.
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the Options panel cannot be reached. |
open_save_as_panel
abstractmethod
¶
Open the Save As panel in the Backstage without confirming a save.
Clicks the "Enregistrer sous" (or locale equivalent) ListItem
and leaves the panel open for manual interaction.
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the panel cannot be reached. |
Source code in src/ezxl/gui/_protocols.py
open_file
abstractmethod
¶
Open the Open panel via the Backstage.
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the panel cannot be reached. |
close_workbook
abstractmethod
¶
Close the active workbook via a Backstage UIA click.
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the action cannot be completed. |
options: show_source: false members: - open_options - open_save_as_panel - open_file - close_workbook
GUI backends — COM (win32com)¶
RibbonProxy
¶
RibbonProxy(app: ExcelApp)
Bases: AbstractRibbonBackend
Ribbon command execution and state queries via MSO identifiers.
Wraps Application.CommandBars methods to execute and inspect
built-in Excel ribbon commands without navigating the UI manually.
| PARAMETER | DESCRIPTION |
|---|---|
app
|
The active
TYPE:
|
Example
proxy = RibbonProxy(xl) proxy.execute("FileSave") proxy.is_enabled("FileSave") True
Source code in src/ezxl/gui/win32com/_ribbon.py
execute
¶
Execute a built-in ribbon command by its MSO identifier.
Calls Application.CommandBars.ExecuteMso(mso_id). Use this
to trigger any standard Excel ribbon button programmatically.
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
MSO control identifier string
(e.g.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the MSO ID is unknown or the command cannot be executed in the current application state. |
Example
ribbon.execute("FileSave")
Source code in src/ezxl/gui/win32com/_ribbon.py
is_enabled
¶
Return whether a ribbon command is currently enabled.
Calls Application.CommandBars.GetEnabledMso(mso_id).
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
MSO control identifier string.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the MSO ID is unknown or the query fails. |
Example
ribbon.is_enabled("FileSave") True
Source code in src/ezxl/gui/win32com/_ribbon.py
is_pressed
¶
Return whether a ribbon toggle command is currently pressed.
Calls Application.CommandBars.GetPressedMso(mso_id).
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
MSO control identifier string.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
Example
ribbon.is_pressed("Bold") False
Source code in src/ezxl/gui/win32com/_ribbon.py
is_visible
¶
Return whether a ribbon command is currently visible.
Calls Application.CommandBars.GetVisibleMso(mso_id).
| PARAMETER | DESCRIPTION |
|---|---|
mso_id
|
MSO control identifier string.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the MSO ID is unknown or the query fails. |
Example
ribbon.is_visible("FileSave") True
Source code in src/ezxl/gui/win32com/_ribbon.py
options: show_source: false members: - execute - is_enabled - is_pressed - is_visible
MenuProxy
¶
MenuProxy(app: ExcelApp)
Bases: AbstractMenuBackend
Legacy CommandBar menu traversal and control execution.
Allows navigating an Excel CommandBar by name and executing controls by their caption path. Also exposes discovery helpers to list all available bars and the top-level controls of any given bar.
| PARAMETER | DESCRIPTION |
|---|---|
app
|
The active
TYPE:
|
Example
proxy = MenuProxy(xl) proxy.list_bars() ['Standard', 'Formatting', ...] proxy.click("Standard", "Open")
Source code in src/ezxl/gui/win32com/_menu.py
click
¶
Traverse a CommandBar by caption path and execute the final control.
Looks up the CommandBar named bar_name, then iterates through
item_path — each element being the caption of a nested control —
descending into sub-controls at each step. Calls .Execute() on
the control identified by the last element.
| PARAMETER | DESCRIPTION |
|---|---|
bar_name
|
The name of the CommandBar to start from
(e.g.
TYPE:
|
*item_path
|
One or more control captions forming the path to the target control. At least one caption is required.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the bar, any intermediate control, or
the final control cannot be found, or if |
Example
menu.click("Standard", "Open") menu.click("Tools", "Macros", "Visual Basic Editor")
Source code in src/ezxl/gui/win32com/_menu.py
list_bars
¶
Return the names of all CommandBars registered with Excel.
Iterates the Application.CommandBars collection and collects
each bar's .Name attribute. Bars with no name are skipped.
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
list[str]: Sorted list of CommandBar names. |
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the COM collection cannot be iterated. |
Example
menu.list_bars() ['3-D Settings', 'Borders', 'Cell', ...]
Source code in src/ezxl/gui/win32com/_menu.py
list_controls
¶
Return the captions of all top-level controls in a CommandBar.
Iterates the .Controls collection of the named bar. Controls
that have no Caption (e.g. separator lines) are skipped.
| PARAMETER | DESCRIPTION |
|---|---|
bar_name
|
The name of the CommandBar to inspect.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
list[str]: Captions of the bar's top-level controls, in order. |
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the bar cannot be found or the controls collection cannot be iterated. |
Example
menu.list_controls("Standard") ['New', 'Open', 'Save', ...]
Source code in src/ezxl/gui/win32com/_menu.py
options: show_source: false members: - click - list_bars - list_controls
DialogProxy
¶
DialogProxy(app: ExcelApp)
Bases: AbstractDialogBackend
File and message dialog helpers backed by Excel COM and Win32.
Provides a clean Python interface for the three most common GUI dialogs needed during Excel automation: open-file picker, save-file picker, and a simple information alert.
| PARAMETER | DESCRIPTION |
|---|---|
app
|
The active
TYPE:
|
Example
proxy = DialogProxy(xl) path = proxy.get_file_open(title="Select a report") if path: ... wb = xl.open(path)
Source code in src/ezxl/gui/win32com/_dialog.py
get_file_open
¶
get_file_open(title: str = 'Open', initial_dir: str | None = None, filter: str = 'Excel Files (*.xls*), *.xls*') -> str | None
Show Excel's built-in Open file picker dialog.
Calls Application.GetOpenFilename. The dialog is modal;
this method blocks until the user confirms or cancels.
| PARAMETER | DESCRIPTION |
|---|---|
title
|
Dialog title bar text. Defaults to
TYPE:
|
initial_dir
|
Directory to open the dialog in. If
TYPE:
|
filter
|
File-type filter string in Excel's two-part format:
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
str | None: Absolute path chosen by the user, or |
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the COM call fails. |
Example
path = dialog.get_file_open(title="Pick a workbook") if path is not None: ... xl.open(path)
Source code in src/ezxl/gui/win32com/_dialog.py
get_file_save
¶
get_file_save(title: str = 'Save As', initial_dir: str | None = None, filter: str = 'Excel Files (*.xlsx), *.xlsx') -> str | None
Show Excel's built-in Save As file picker dialog.
Calls Application.GetSaveAsFilename. The dialog is modal;
this method blocks until the user confirms or cancels.
| PARAMETER | DESCRIPTION |
|---|---|
title
|
Dialog title bar text. Defaults to
TYPE:
|
initial_dir
|
Directory to open the dialog in. If
TYPE:
|
filter
|
File-type filter string in Excel's two-part format:
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
str | None: Absolute path chosen by the user, or |
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the COM call fails. |
Example
path = dialog.get_file_save(title="Save report as") if path is not None: ... wb.save_as(path)
Source code in src/ezxl/gui/win32com/_dialog.py
alert
¶
Display a modal information message box.
Uses ctypes.windll.user32.MessageBoxW (Win32 API) directly.
This approach avoids any dependency on a running VBA environment
and does not require Excel to have a document open.
The dialog shows a single OK button with an information icon. This method blocks until the user dismisses the dialog.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
The body text displayed in the message box.
TYPE:
|
title
|
Caption for the message box title bar.
Defaults to
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the Win32 MessageBoxW call fails. |
Example
dialog.alert("Export complete.", title="Success")
Source code in src/ezxl/gui/win32com/_dialog.py
options: show_source: false members: - get_file_open - get_file_save - alert
COMBackstageBackend
¶
COMBackstageBackend(app: ExcelApp)
Bases: AbstractBackstageFileOps
Excel Backstage file operations via the COM object model.
Implements :class:~ezxl.gui._protocols.AbstractBackstageFileOps using
Excel's COM API. All operations are focus-independent and
locale-independent.
This is the default backstage backend for :class:~ezxl.gui.GUIProxy.
For UIA-based Backstage navigation (Options panel, visual panel
opening), inject a
:class:~ezxl.gui.pywinauto.PywinautoBackstageBackend as the
backstage_nav argument::
gui = GUIProxy(
xl,
backstage=COMBackstageBackend(xl),
backstage_nav=PywinautoBackstageBackend(hwnd=xl.hwnd, locale="fr"),
)
| PARAMETER | DESCRIPTION |
|---|---|
app
|
The active
TYPE:
|
Example
backend = COMBackstageBackend(xl) backend.save() backend.save_as(path="C:\Reports\output.xlsx") backend.open_file() backend.close_workbook()
Source code in src/ezxl/gui/win32com/_backstage.py
save
¶
Save the active workbook via ActiveWorkbook.Save().
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If no workbook is currently open. |
COMOperationError
|
If the COM call fails. |
Example
backend.save()
Source code in src/ezxl/gui/win32com/_backstage.py
save_as
¶
Save the active workbook under a new path, or show the Save As dialog.
If path is provided, calls ActiveWorkbook.SaveAs(Filename=path)
directly — no dialog is shown. If path is None, opens the
built-in Excel Save As dialog (xlDialogSaveAs), which blocks until
the user dismisses it.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
Absolute path for the new file. If
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If no workbook is currently open. |
COMOperationError
|
If the COM call fails. |
Example
backend.save_as() # opens dialog backend.save_as(path="C:\output.xlsx") # direct save
Source code in src/ezxl/gui/win32com/_backstage.py
open_file
¶
Show the built-in Excel Open dialog (xlDialogOpen).
The dialog blocks until the user selects a file or cancels.
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
COMOperationError
|
If the COM call fails. |
Example
backend.open_file()
Source code in src/ezxl/gui/win32com/_backstage.py
close_workbook
¶
Close the active workbook without saving (SaveChanges=False).
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
WorkbookNotFoundError
|
If no workbook is currently open. |
COMOperationError
|
If the COM call fails. |
Example
backend.close_workbook()
Source code in src/ezxl/gui/win32com/_backstage.py
open_options
¶
Open the Excel Options dialog via CommandBars.ExecuteMso.
This method is not part of :class:AbstractBackstageFileOps.
It is provided as a convenience fallback when
:class:~ezxl.gui.pywinauto.PywinautoBackstageBackend (the
preferred implementation via :class:AbstractBackstageNavigator)
is unavailable.
Uses the "ApplicationOptionsDialog" MSO identifier. This may
fail in restricted environments (e.g. when a macro is running or the
ribbon is disabled).
| RAISES | DESCRIPTION |
|---|---|
ExcelThreadViolationError
|
If called from the wrong thread. |
GUIOperationError
|
If the Options dialog cannot be opened via COM. |
Example
backend.open_options()
Source code in src/ezxl/gui/win32com/_backstage.py
options: show_source: false members: - save - save_as - open_file - close_workbook
GUI backends — pywinauto¶
PywinautoKeysBackend
¶
Bases: AbstractKeysBackend
Keystroke injection via pywinauto.keyboard.send_keys.
Translates VBA SendKeys notation to pywinauto notation using
:func:_translate_keys, then delegates to
pywinauto.keyboard.send_keys.
This backend is a standalone alternative to the COM-based
_COMKeysBackend. It does not require an
:class:~ezxl.core.ExcelApp instance and carries no COM STA
thread constraint.
| PARAMETER | DESCRIPTION |
|---|---|
hwnd
|
Win32 window handle for the Excel main window. Currently
unused —
TYPE:
|
Example
from ezxl.gui.pywinauto import PywinautoKeysBackend keys = PywinautoKeysBackend() keys.send_keys("^s") # Ctrl+S keys.send_keys("{ESCAPE}") # maps to {ESC} internally keys.send_keys("^{HOME}")
Inject into GUIProxy:¶
from ezxl import ExcelApp, GUIProxy with ExcelApp(mode="attach") as xl: ... gui = GUIProxy(xl, keys=PywinautoKeysBackend()) ... gui.send_keys("^{HOME}")
Source code in src/ezxl/gui/pywinauto/_keys.py
send_keys
¶
Send a keystroke sequence using pywinauto.keyboard.
Translates keys from VBA SendKeys notation to pywinauto notation
via :func:_translate_keys, then calls
pywinauto.keyboard.send_keys. If wait is True, a brief
pause of 50 ms is inserted after injection as a best-effort
approximation of the VBA wait=True semantics.
Note
pywinauto.keyboard.send_keys injects keystrokes into
the currently focused window. Call
window.set_focus() on the Excel window before using
this backend if focus cannot be guaranteed.
| PARAMETER | DESCRIPTION |
|---|---|
keys
|
Keystroke string in VBA SendKeys notation
(e.g.
TYPE:
|
wait
|
If
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the pywinauto keystroke injection raises an unexpected error. |
Example
backend.send_keys("^s") # Ctrl+S backend.send_keys("{ESCAPE}") # → {ESC} internally backend.send_keys("%{F4}", wait=False) # Alt+F4, no pause
Source code in src/ezxl/gui/pywinauto/_keys.py
options: show_source: false members: - send_keys
PywinautoBackstageBackend
¶
Bases: AbstractBackstageNavigator
Excel Backstage visual navigation via UIA direct click with Alt-sequence fallback.
Implements :class:~ezxl.gui._protocols.AbstractBackstageNavigator using
pywinauto. The primary strategy for every action is a UIA direct
click — the backend opens the Backstage via Button "Onglet Fichier"
(or locale equivalent), then clicks the target ListItem by its
localised UIA Name. This approach is focus-independent.
An Alt-sequence fallback is attempted only when the UIA click fails
and the element spec carries a non-empty alt_sequence.
This backend does not perform file I/O. Operations that write to
disk (save, save_as with an explicit path) belong to
:class:~ezxl.gui.win32com.COMBackstageBackend and are exposed through
GUIProxy.backstage. This backend is composed alongside it via
GUIProxy.backstage_nav.
| PARAMETER | DESCRIPTION |
|---|---|
hwnd
|
Win32 window handle for the Excel main window. Pass
TYPE:
|
locale
|
Locale code used for UIA
TYPE:
|
Example
backend = PywinautoBackstageBackend(hwnd=xl.hwnd, locale="fr") backend.open_options() # UIA: opens Options panel backend.open_save_as_panel() # UIA: opens Save As panel, leaves open backend.open_file() # UIA: opens Open panel backend.close_workbook() # UIA: clicks Close in Backstage
Source code in src/ezxl/gui/pywinauto/_backstage.py
open_options
¶
Navigate to the Excel Options panel via the Backstage.
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the Options panel cannot be reached. |
Example
backend.open_options()
Source code in src/ezxl/gui/pywinauto/_backstage.py
open_save_as_panel
¶
Open the Save As panel in the Backstage without confirming a save.
Clicks the "Enregistrer sous" (or locale equivalent) ListItem
and leaves the panel open. Does not write to disk — use
GUIProxy.backstage.save_as(path=...) for programmatic saves.
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the panel cannot be reached. |
Example
backend.open_save_as_panel()
Source code in src/ezxl/gui/pywinauto/_backstage.py
open_file
¶
Open the Open panel via the Backstage.
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the panel cannot be reached. |
Example
backend.open_file()
Source code in src/ezxl/gui/pywinauto/_backstage.py
close_workbook
¶
Close the active workbook via a Backstage UIA click.
| RAISES | DESCRIPTION |
|---|---|
GUIOperationError
|
If the action cannot be completed. |
Example
backend.close_workbook()
Source code in src/ezxl/gui/pywinauto/_backstage.py
options: show_source: false members: - init - open_options - open_save_as_panel - open_file - close_workbook
File I/O¶
read_excel
¶
Read an Excel workbook sheet into a polars DataFrame.
Delegates to polars.read_excel which uses fastexcel (Rust)
under the hood. No running Excel process is required.
| PARAMETER | DESCRIPTION |
|---|---|
source
|
Path to the source
TYPE:
|
sheet
|
Worksheet name to read. Pass
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
pl.DataFrame: Contents of the requested sheet as a polars |
DataFrame
|
DataFrame, with the first row used as column headers. |
| RAISES | DESCRIPTION |
|---|---|
FileNotFoundError
|
If |
ImportError
|
If polars (or its |
Example
df = read_excel("report.xlsx", sheet="Data") print(df.head())
Source code in src/ezxl/io/_converters.py
options: show_source: false
read_csv
¶
Read a CSV file into a polars DataFrame.
| PARAMETER | DESCRIPTION |
|---|---|
source
|
Path to the source
TYPE:
|
separator
|
Column delimiter character. Defaults to
TYPE:
|
encoding
|
File encoding passed through to polars. Defaults to
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
pl.DataFrame: Parsed contents of the CSV file. |
| RAISES | DESCRIPTION |
|---|---|
FileNotFoundError
|
If |
Example
df = read_csv("transactions.csv", separator=";") print(df.schema)
Source code in src/ezxl/io/_converters.py
options: show_source: false
xlsx_to_csv
¶
xlsx_to_csv(source: str | Path, dest: str | Path, sheet: str | None = None, separator: str = ',') -> None
Convert an Excel workbook sheet to a CSV file using polars.
Supersedes both the former xlsx_to_csv (openpyxl) and
xlsx_to_csv_fast (python-calamine) functions. polars uses
fastexcel (Rust) for the read step, providing the same
high-throughput characteristics as the former fast path.
| PARAMETER | DESCRIPTION |
|---|---|
source
|
Path to the source
TYPE:
|
dest
|
Destination
TYPE:
|
sheet
|
Worksheet name to export. Pass
TYPE:
|
separator
|
Column delimiter for the CSV output. Defaults to
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
FileNotFoundError
|
If |
Example
xlsx_to_csv("data.xlsx", "data.csv", sheet="Transactions") xlsx_to_csv("data.xlsx", "data.tsv", separator="\t")
Source code in src/ezxl/io/_converters.py
options: show_source: false
csv_to_xlsx
¶
Convert a CSV file to an Excel workbook using polars.
Reads the CSV with polars and writes it as an .xlsx file.
polars delegates the Excel write step to xlsxwriter or
openpyxl depending on which is installed; no additional
configuration is required.
| PARAMETER | DESCRIPTION |
|---|---|
source
|
Path to the source
TYPE:
|
dest
|
Destination
TYPE:
|
sheet_name
|
Name of the worksheet to create in the output
workbook. Defaults to
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
FileNotFoundError
|
If |
Example
csv_to_xlsx("transactions.csv", "transactions.xlsx", sheet_name="Data")
Source code in src/ezxl/io/_converters.py
options: show_source: false
read_sheet
¶
Read a worksheet into a row-major list of lists (compatibility shim).
Wraps read_excel and converts the resulting polars DataFrame to
a list[list[Any]] via DataFrame.rows(). The first row
contains the column headers as extracted by polars.
This function exists for backwards compatibility with callers that
pre-date the polars migration. New code should use read_excel
directly to benefit from the full polars API.
| PARAMETER | DESCRIPTION |
|---|---|
source
|
Path to the source
TYPE:
|
sheet
|
Worksheet name to read. Pass
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[list[Any]]
|
list[list[Any]]: Row-major 2D list of cell values. The first |
list[list[Any]]
|
row contains column headers; subsequent rows contain data |
list[list[Any]]
|
values. Empty cells are represented as |
| RAISES | DESCRIPTION |
|---|---|
FileNotFoundError
|
If |
Example
data = read_sheet("report.xlsx", sheet="Data") headers = data[0] rows = data[1:]
Source code in src/ezxl/io/_converters.py
options: show_source: false
Closed-file formatting¶
ExcelFormatter
¶
Fluent formatter for closed Excel workbook files.
All formatting operations are buffered and applied in a single write
pass when save() is called. The workbook is opened with openpyxl
only at save time, minimising I/O overhead.
The API is intentionally flat: no sheet selector is exposed here. The
formatter operates on the active sheet of the workbook. Consumer
libraries that need multi-sheet formatting should instantiate one
ExcelFormatter per sheet operation.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
Path to an existing
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
FileNotFoundError
|
If |
ImportError
|
If openpyxl is not installed. |
Example
( ... ExcelFormatter("report.xlsx") ... .column_width("A", 20) ... .font("A1", bold=True, size=14, color="FFFFFF") ... .fill("A1", "4F81BD") ... .save() ... )
Source code in src/ezxl/io/_formatters.py
column_width
¶
column_width(col: str, width: float) -> ExcelFormatter
Set the width of a column.
| PARAMETER | DESCRIPTION |
|---|---|
col
|
Column letter (e.g.
TYPE:
|
width
|
Column width in Excel character units.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ExcelFormatter
|
TYPE:
|
Example
formatter.column_width("A", 20).column_width("B", 15)
Source code in src/ezxl/io/_formatters.py
row_height
¶
row_height(row: int, height: float) -> ExcelFormatter
Set the height of a row.
| PARAMETER | DESCRIPTION |
|---|---|
row
|
1-based row index.
TYPE:
|
height
|
Row height in points.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ExcelFormatter
|
TYPE:
|
Example
formatter.row_height(1, 30)
Source code in src/ezxl/io/_formatters.py
font
¶
font(ref: str, *, bold: bool = False, italic: bool = False, size: int | None = None, color: str | None = None) -> ExcelFormatter
Apply font formatting to a cell or range.
| PARAMETER | DESCRIPTION |
|---|---|
ref
|
Cell or range address in A1 notation (e.g.
TYPE:
|
bold
|
Apply bold weight. Defaults to
TYPE:
|
italic
|
Apply italic style. Defaults to
TYPE:
|
size
|
Font size in points.
TYPE:
|
color
|
Font colour as a 6-character hex string without
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ExcelFormatter
|
TYPE:
|
Example
formatter.font("A1", bold=True, size=12, color="FF0000")
Source code in src/ezxl/io/_formatters.py
fill
¶
fill(ref: str, color: str) -> ExcelFormatter
Apply a solid background fill to a cell or range.
| PARAMETER | DESCRIPTION |
|---|---|
ref
|
Cell or range address in A1 notation.
TYPE:
|
color
|
Background colour as a 6-character hex string without
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ExcelFormatter
|
TYPE:
|
Example
formatter.fill("A1:D1", "4F81BD")
Source code in src/ezxl/io/_formatters.py
border
¶
border(ref: str, style: str = 'thin') -> ExcelFormatter
Apply a border to all edges of a cell or range.
| PARAMETER | DESCRIPTION |
|---|---|
ref
|
Cell or range address in A1 notation.
TYPE:
|
style
|
Border style name as understood by openpyxl
(e.g.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ExcelFormatter
|
TYPE:
|
Example
formatter.border("A1:D5", style="thin")
Source code in src/ezxl/io/_formatters.py
align
¶
align(ref: str, *, horizontal: str | None = None, vertical: str | None = None, wrap: bool = False) -> ExcelFormatter
Apply alignment to a cell or range.
| PARAMETER | DESCRIPTION |
|---|---|
ref
|
Cell or range address in A1 notation.
TYPE:
|
horizontal
|
Horizontal alignment. Accepted values:
TYPE:
|
vertical
|
Vertical alignment. Accepted values:
TYPE:
|
wrap
|
Enable text wrapping. Defaults to
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ExcelFormatter
|
TYPE:
|
Example
formatter.align("A1", horizontal="center", vertical="top", wrap=True)
Source code in src/ezxl/io/_formatters.py
save
¶
Apply all buffered operations and write the workbook.
| PARAMETER | DESCRIPTION |
|---|---|
dest
|
Destination path. Pass
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
FormatterError
|
If any openpyxl operation fails. |
ImportError
|
If openpyxl is not installed. |
Example
formatter.save() # overwrite source formatter.save("output/report.xlsx") # write to new path
Source code in src/ezxl/io/_formatters.py
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | |
options: show_source: false members: - init - column_width - row_height - font - fill - border - align - save