xlwings: Excel Automation Guide
xlwings: Excel Automation Guide
Release dev
1 Video course 1
2 Installation 3
2.1 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Add-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.4 Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.5 How to activate xlwings PRO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.6 Optional Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.7 Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.8 Uninstall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3 Quickstart 7
3.1 1. Interacting with Excel from a Jupyter notebook . . . . . . . . . . . . . . . . . . . . . . 7
3.2 2. Scripting: Automate/interact with Excel from Python . . . . . . . . . . . . . . . . . . . 7
3.3 3. Macros: Call Python from Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.4 4. UDFs: User Defined Functions (Windows only) . . . . . . . . . . . . . . . . . . . . . . 9
4 Connect to a Book 11
4.1 Python to Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.2 Excel to Python (RunPython) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
4.3 User Defined Functions (UDFs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5 Syntax Overview 13
5.1 Active Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5.2 Full qualification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5.3 Range indexing/slicing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5.4 Range Shortcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5.5 Object Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
i
6.3 Range expanding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
6.4 NumPy arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
6.5 Pandas DataFrames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
6.6 Pandas Series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
8 RunPython 27
8.1 xlwings add-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
8.2 Call Python with “RunPython” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
8.3 Function Arguments and Return Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
13 xlwings Reports 47
13.1 Quickstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
13.2 Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
13.3 Excel Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
ii
13.4 Excel Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
13.5 Shape Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
14 Deployment 59
14.1 Zip files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
14.2 RunFrozenPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
14.3 Embedded Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
14.4 One-Click Zero-Config Installer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
14.5 Deployment Key . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
15 Troubleshooting 65
15.1 Issue: dll not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
15.2 Issue: Couldn’t find the local location of your OneDrive . . . . . . . . . . . . . . . . . . . 65
16 xlwings PRO 67
16.1 PRO Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
16.2 More Infos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
18 Debugging 81
18.1 RunPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
18.2 UDF debug server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
19 Extensions 85
19.1 In-Excel SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
20 Custom Add-ins 87
20.1 Quickstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
20.2 Changing the Ribbon menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
20.3 Importing UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
20.4 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
20.5 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
20.6 Renaming your add-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
20.7 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
22 Missing Features 97
22.1 Example: Workaround to use VBA’s [Link] . . . . . . . . . . . . . . . . . . 97
iii
24 xlwings with R and Julia 101
24.1 R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
24.2 Julia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Index 175
iv
CHAPTER 1
Video course
Those who prefer a didactically structured video course over this documentation should have a look at our
video course:
[Link]
It’s also a great way to support the ongoing development of xlwings :)
1
xlwings - Make Excel Fly!, Release dev
Installation
2.1 Prerequisites
• xlwings requires an installation of Excel and therefore only works on Windows and macOS. Note
that macOS currently does not support UDFs.
• xlwings requires at least Python 3.6.
Here are the last versions of xlwings to support:
• Python 3.5: 0.19.5
• Python 2.7: 0.16.6
2.2 Installation
or conda:
3
xlwings - Make Excel Fly!, Release dev
Note that the official conda package might be a few releases behind. You can, however, use the
conda-forge channel (replace install with upgrade if xlwings is already installed):
Note: When you are on macOS and are installing xlwings with conda (or use the version that comes with
Anaconda), you’ll need to run $ xlwings runpython install once to enable the RunPython
calls from VBA. This is done automatically if you install the addin via $ xlwings addin install.
2.3 Add-in
To call Excel from Python, you don’t need an add-in. Also, you can use a single file VBA module (stan-
dalone workbook) instead of the add-in. For more details, see Add-in & Settings.
Note: The add-in needs to be the same version as the Python package. Make sure to re-install the add-in
after upgrading the xlwings package.
2.4 Dependencies
• Windows: pywin32
• Mac: psutil, appscript
The dependencies are automatically installed via conda or pip.
xlwings PRO offers access to additional functionality. All PRO features are marked with xlwings PRO in
the docs.
Note: To get access to the additional functionality of xlwings PRO, you need a license key and at least xl-
wings v0.19.0. Everything under the [Link] subpackage is distributed under a commercial license.
See xlwings PRO for more details.
4 Chapter 2. Installation
xlwings - Make Excel Fly!, Release dev
Make sure to replace LICENSE_KEY with your personal key. This will store the license key under your
[Link] file (see User Config: Ribbon/Config File for where this is on your system). Alternatively,
you can also store the license key as an environment variable with the name XLWINGS_LICENSE_KEY.
xlwings PRO requires additionally the cryptography and Jinja2 packages which come preinstalled
with Anaconda and WinPython. Otherwise, install them via pip or conda.
With pip, you can also run pip install "xlwings[pro]" which will take care of the extra depen-
dencies for xlwings PRO.
• NumPy
• Pandas
• Matplotlib
• Pillow/PIL
• Flask (for REST API)
• cryptography (for [Link])
• Jinja2 (for [Link])
These packages are not required but highly recommended as they play very nicely with xlwings. They are
all pre-installed with Anaconda. With pip, you can install xlwings with all optional dependencies as follows:
2.7 Update
To update to the latest xlwings version, run the following in a command prompt:
or:
Make sure to keep your version of the Excel add-in in sync with your Python package by running the
following (make sure to close Excel first):
2.8 Uninstall
To uninstall xlwings completely, first uninstall the add-in, then uninstall the xlwings package using the same
method (pip or conda) that you used for installing it:
Then
or:
Finally, manually remove the .xlwings directory in your home folder if it exists.
6 Chapter 2. Installation
CHAPTER 3
Quickstart
This guide assumes you have xlwings already installed. If that’s not the case, head over to Installation.
If you’re just interested in getting a pandas DataFrame in and out of your Jupyter notebook, you can use the
view and load functions, see Jupyter Notebooks: Interact with Excel.
If you have the same file open in two instances of Excel, you need to fully qualify it and include the app
instance. You will find your app instance key (the PID) via [Link]():
>>> [Link][10559].books['[Link]']
7
xlwings - Make Excel Fly!, Release dev
>>> [Link]('A1').value = [['Foo 1', 'Foo 2', 'Foo 3'], [10.0, 20.0, 30.0]]
>>> [Link]('A1').expand().value
[['Foo 1', 'Foo 2', 'Foo 3'], [10.0, 20.0, 30.0]]
Powerful converters handle most data types of interest, including Numpy arrays and Pandas DataFrames
in both directions:
You can call Python functions either by clicking the Run button (new in v0.16) in the add-in or from VBA
using the RunPython function:
The Run button expects a function called main in a Python module with the same name as your workbook.
The great thing about that approach is that you don’t need your workbooks to be macro-enabled, you can
save it as xlsx.
If you want to call any Python function no matter in what module it lives or what name it has, use
RunPython:
Sub HelloWorld()
RunPython "import hello; [Link]()"
End Sub
Note: Per default, RunPython expects [Link] in the same directory as the Excel file with the same
name, but you can change both of these things: if your Python file is an a different folder, add that folder
8 Chapter 3. Quickstart
xlwings - Make Excel Fly!, Release dev
to the PYTHONPATH in the config. If the file has a different name, change the RunPython command
accordingly.
# [Link]
import numpy as np
import xlwings as xw
def world():
wb = [Link]()
[Link][0].range('A1').value = 'Hello World!'
To make this run, you’ll need to have the xlwings add-in installed or have the workbooks setup in the
standalone mode. The easiest way to get everything set up is to use the xlwings command line client from
either a command prompt on Windows or a terminal on Mac: xlwings quickstart myproject.
For details about the addin, see Add-in & Settings.
import xlwings as xw
@[Link]
def hello(name):
return 'Hello {0}'.format(name)
Converters can be used with UDFs, too. Again a Pandas DataFrame example:
import xlwings as xw
import pandas as pd
@[Link]
@[Link]('x', [Link])
def correl2(x):
# x arrives as DataFrame
return [Link]()
Import this function into Excel by clicking the import button of the xlwings add-in: For a step-by-step
tutorial, see User Defined Functions (UDFs).
10 Chapter 3. Quickstart
CHAPTER 4
Connect to a Book
When reading/writing data to the active sheet, you don’t need a book object:
The easiest way to connect to a book is offered by [Link]: it looks for the book in all app instances and
returns an error, should the same book be open in multiple instances. To connect to a book in the active app
instance, use [Link] and to refer to a specific app, use:
>>> app = [Link]() # or something like [Link][10559] for existing apps, get
˓→the available PIDs via [Link]()
>>> [Link]['Book1']
[Link] [Link]
New book [Link]() [Link]()
Unsaved book [Link]('Book1') [Link]['Book1']
Book by [Link](r'C:/path/to/ [Link](r'C:/path/to/
(full)name [Link]') [Link]')
Note: When specifying file paths on Windows, you should either use raw strings by putting an r in front
of the string or use double back-slashes like so: C:\\path\\to\\[Link].
11
xlwings - Make Excel Fly!, Release dev
To reference the calling book when using RunPython in VBA, use [Link](), see Call
Python with “RunPython”. Check out the section about Debugging to see how you can call a script from
both sides, Python and Excel, without the need to constantly change between [Link]() and
one of the methods explained above.
Unlike RunPython, UDFs don’t need a call to [Link](), see User Defined Functions
(UDFs). You’ll usually use the caller argument which returns the xlwings range object from where
you call the function.
Syntax Overview
The xlwings object model is very similar to the one used by VBA.
All code samples below depend on the following import:
# Active book
>>> wb = [Link] # in active app
>>> wb = [Link] # in specific app
# Active sheet
>>> sht = [Link] # in active book
>>> sht = [Link] # in specific book
A Range can be instantiated with A1 notation, a tuple of Excel’s 1-based indices, a named range or two
Range objects:
[Link]('A1')
[Link]('A1:C3')
[Link]((1,1))
(continues on next page)
13
xlwings - Make Excel Fly!, Release dev
Round brackets follow Excel’s behavior (i.e. 1-based indexing), while square brackets use Python’s 0-based
indexing/slicing. As an example, the following expressions all reference the same range:
[Link][763].books[0].sheets[0].range('A1')
[Link](10559).books(1).sheets(1).range('A1')
[Link][763].books['Book1'].sheets['Sheet1'].range('A1')
[Link](10559).books('Book1').sheets('Sheet1').range('A1')
Note that the apps keys are different for you as they are the process IDs (PID). You can get the list of your
PIDs via [Link]().
Sheet objects offer a shortcut for range objects by using index/slice notation on the sheet object. This evalu-
ates to either [Link] or [Link] depending on whether you pass a string or indices/slices:
The following shows an example of the object hierarchy, i.e. how to get from an app to a range object and
all the way back:
This tutorial gives you a quick introduction to the most common use cases and default behaviour of xlwings
when reading and writing values. For an in-depth documentation of how to control the behavior using the
options method, have a look at Converters and Options.
All code samples below depend on the following import:
Single cells are by default returned either as float, unicode, None or datetime objects, depending
on whether the cell contains a number, a string, is empty or represents a date:
17
xlwings - Make Excel Fly!, Release dev
6.2 Lists
• 1d lists: Ranges that represent rows or columns in Excel are returned as simple lists, which means
that once they are in Python, you’ve lost the information about the orientation. If that is an issue, the
next point shows you how to preserve this info:
>>> [Link]('A1').options(ndim=1).value
[1.0]
• 2d lists: If the row or column orientation has to be preserved, set ndim in the Range options. This
will return the Ranges as nested lists (“2d lists”):
>>> [Link]('A1:A5').options(ndim=2).value
[[1.0], [2.0], [3.0], [4.0], [5.0]]
>>> [Link]('A1:E1').options(ndim=2).value
[[1.0, 2.0, 3.0, 4.0, 5.0]]
• 2 dimensional Ranges are automatically returned as nested lists. When assigning (nested) lists to a
Range in Excel, it’s enough to just specify the top left cell as target address. This sample also makes
use of index notation to read the values back into Python:
>>> [Link]('A10').value = [['Foo 1', 'Foo 2', 'Foo 3'], [10, 20, 30]]
>>> [Link]((10,1),(11,3)).value
[['Foo 1', 'Foo 2', 'Foo 3'], [10.0, 20.0, 30.0]]
Note: Try to minimize the number of interactions with Excel. It is always more efficient to do
[Link]('A1').value = [[1,2],[3,4]] than [Link]('A1').value = [1, 2]
and [Link]('A2').value = [3, 4].
You can get the dimensions of Excel Ranges dynamically through either the method expand or through the
expand keyword in the options method. While expand gives back an expanded Range object, options
are only evaluated when accessing the values of a Range. The difference is best explained with an example:
>>> sht = [Link]().sheets[0]
>>> [Link]('A1').value = [[1,2], [3,4]]
>>> rng1 = [Link]('A1').expand('table') # or just .expand()
>>> rng2 = [Link]('A1').options(expand='table')
>>> [Link]
[[1.0, 2.0], [3.0, 4.0]]
>>> [Link]
[[1.0, 2.0], [3.0, 4.0]]
>>> [Link]('A3').value = [5, 6]
>>> [Link]
[[1.0, 2.0], [3.0, 4.0]]
>>> [Link]
[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]
'table' expands to 'down' and 'right', the other available options which can be used for column or
row only expansion, respectively.
Note: Using expand() together with a named Range as top left cell gives you a flexible setup in Excel:
You can move around the table and change its size without having to adjust your code, e.g. by using
something like [Link]('NamedRange').expand().value.
NumPy arrays work similar to nested lists. However, empty cells are represented by nan instead of None.
If you want to read in a Range as array, set convert=[Link] in the options method:
>>> import numpy as np
>>> sht = [Link]().sheets[0]
>>> [Link]('A1').value = [Link](3)
>>> [Link]('A1').options([Link], expand='table').value
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
Note: You only need to specify the top left cell when writing a list, a NumPy array or a Pandas DataFrame
to Excel, e.g.: [Link]('A1').value = [Link](10)
The xlwings add-in is the preferred way to be able to use the Run main button, RunPython or UDFs.
Note that you don’t need an add-in if you just want to manipulate Excel by running a Python script.
Note: The ribbon of the add-in is compatible with Excel >= 2007 on Windows and >= 2016 on Mac. On
Mac, all UDF related functionality is not available.
Note: The add-in is password protected with the password xlwings. For debugging or to add new
extensions, you need to unprotect it. Alternatively, you can also install the add-in via xlwings addin
install --unprotected.
21
xlwings - Make Excel Fly!, Release dev
7.2 Installation
Technically, this copies the add-in from Python’s installation directory to Excel’s XLSTART folder. Then,
to use RunPython or UDFs in a workbook, you need to set a reference to xlwings in the VBA editor,
see screenshot (Windows: Tools > References..., Mac: it’s on the lower left corner of the VBA
editor). Note that when you create a workbook via xlwings quickstart, the reference should already
be set.
When you install the add-in for the first time, it will get auto-configured and therefore, a quickstart
project should work out of the box. For fine-tuning, here are the available settings:
• Interpreter: This is the path to the Python interpreter. This works also with virtual or conda
envs on Mac. If you use conda envs on Windows, then leave this empty and use Conda Path
and Conda Env below instead. Examples: "C:\Python39\[Link]" or "/usr/
local/bin/python3.9". Note that in the settings, this is stored as Interpreter_Win or
Interpreter_Mac, respectively, see below!
• PYTHONPATH: If the source file of your code is not found, add the path to its directory here.
• Conda Path: If you are on Windows and use Anaconda or Miniconda, then type here the path to
your installation, e.g. C:\Users\Username\Miniconda3 or %USERPROFILE%\Anaconda.
NOTE that you need at least conda 4.6! You also need to set Conda Env, see next point.
• Conda Env: If you are on Windows and use Anaconda or Miniconda, type here the name of your
conda env, e.g. base for the base installation or myenv for a conda env with the name myenv.
• UDF Modules: Names of Python modules (without .py extension) from which the UDFs are be-
ing imported. Separate multiple modules by “;”. Example: UDF_MODULES = "common_udfs;
myproject" The default imports a file in the same directory as the Excel spreadsheet with the same
name but ending in .py.
• Debug UDFs: Check this box if you want to run the xlwings COM server manually for debugging,
see Debugging.
• RunPython: Use UDF Server: Uses the same COM Server for RunPython as for UDFs. This
will be faster, as the interpreter doesn’t shut down after each call.
• Restart UDF Server: This restarts the UDF Server/Python interpreter.
• Show Console: Check the box in the ribbon or set the config to TRUE if you want the command
prompt to pop up. This currently only works on Windows.
7.3.1 Anaconda/Miniconda
If you use Anaconda or Miniconda on Windows, you will need to set your Conda Path and Conda Env
settings, as you will otherwise get errors when using NumPy etc. In return, leave Interpreter empty.
With environment variables, you can set dynamic paths e.g. to your interpreter or PYTHONPATH:
• On Windows, you can use all environment variables like so: %USERPROFILE%\Anaconda.
• On macOS, the following special variables are supported: $HOME, $APPLICATIONS,
$DOCUMENTS, $DESKTOP.
The settings in the xlwings Ribbon are stored in a config file that can also be manipulated externally. The
location is
• Windows: .xlwings\[Link] in your home folder, that is usually
C:\Users\<username>
• macOS: ~/Library/Containers/[Link]/Data/[Link]
The format is as follows (currently the keys are required to be all caps) - note the OS specific Interpreter
settings!
"INTERPRETER_WIN","C:\path\to\[Link]"
"INTERPRETER_MAC","/path/to/python"
"PYTHONPATH",""
"CONDA PATH",""
"CONDA ENV",""
"UDF MODULES",""
"DEBUG UDFS",""
"USE UDF SERVER",""
"SHOW CONSOLE",""
"ONEDRIVE",""
Note: The ONEDRIVE setting has to be edited directly in the file, there is currently no possibility to edit
it via the ribbon. Usually, it is only required if you are either on macOS or if your environment vars on
Windows are not correctly set or if you have a private and corporate location and don’t want to go with the
default one. ONEDRIVE has to point to the root folder of your local OneDrive folder.
The global settings of the Ribbon/Config file can be overridden for one or more workbooks by creating a
[Link] file in the workbook’s directory.
Workbook specific settings will override global (Ribbon) and workbook directory config files: Workbook
specific settings are set by listing the config key/value pairs in a sheet with the name [Link].
When you create a new project with xlwings quickstart, it’ll already have such a sheet but you need
to rename it to [Link] to make it active.
Sometimes, it might be useful to run xlwings code without having to install an add-in first. To do so, you need
to use the standalone option when creating a new project: xlwings quickstart myproject
--standalone.
This will add the content of the add-in as a single VBA module so you don’t need to set a reference to
the add-in anymore. It will also include [Link] as this is required on macOS. It will still
read in the settings from your [Link] if you don’t override them by using a sheet with the name
[Link].
RunPython
To get access to Run main (new in v0.16) button or the RunPython VBA function, you’ll need the
xlwings addin (or VBA module), see Add-in & Settings.
For new projects, the easiest way to get started is by using the command line client with the quickstart
command, see Command Line Client (CLI) for details:
In the VBA Editor (Alt-F11), write the code below into a VBA module. xlwings quickstart
automatically adds a new module with a sample call. If you rather want to start from scratch, you can add a
new module via Insert > Module.
Sub HelloWorld()
RunPython ("import hello; [Link]()")
End Sub
# [Link]
import numpy as np
import xlwings as xw
def world():
(continues on next page)
27
xlwings - Make Excel Fly!, Release dev
You can then attach HelloWorld to a button or run it directly in the VBA Editor by hitting F5.
Note: Place [Link]() within the function that is being called from Excel and not outside as
global variable. Otherwise it prevents Excel from shutting down properly upon exiting and leaves you with
a zombie process when you use Use UDF Server = True.
While it’s technically possible to include arguments in the function call within RunPython, it’s not very
convenient. Also, RunPython does not allow you to return values. To overcome these issues, use UDFs,
see User Defined Functions (UDFs) - however, this is currently limited to Windows only.
28 Chapter 8. RunPython
CHAPTER 9
This tutorial gets you quickly started on how to write User Defined Functions.
Note:
• UDFs are currently only available on Windows.
• For details of how to control the behaviour of the arguments and return values, have a look at Con-
verters and Options.
• For a comprehensive overview of the available decorators and their options, check out the correspond-
ing API docs: UDF decorators.
1) Enable Trust access to the VBA project object model under File > Options >
Trust Center > Trust Center Settings > Macro Settings
2) Install the add-in via command prompt: xlwings addin install (see Add-in & Settings).
The easiest way to start a new project is to run xlwings quickstart myproject on a command
prompt (see Command Line Client (CLI)). This automatically adds the xlwings reference to the generated
workbook.
29
xlwings - Make Excel Fly!, Release dev
The default addin settings expect a Python source file in the way it is created by quickstart:
• in the same directory as the Excel file
• with the same name as the Excel file, but with a .py ending instead of .xlsm.
Alternatively, you can point to a specific module via UDF Modules in the xlwings ribbon.
Let’s assume you have a Workbook [Link], then you would write the following code in
[Link]:
import xlwings as xw
@[Link]
def double_sum(x, y):
"""Returns twice the sum of the two arguments"""
return 2 * (x + y)
• Now click on Import Python UDFs in the xlwings tab to pick up the changes made to
[Link].
• Enter the formula =double_sum(1, 2) into a cell and you will see the correct result:
Note:
• You only need to re-import your functions if you change the function arguments or the function name.
• Code changes in the actual functions are picked up automatically (i.e. at the next calculation of the
formula, e.g. triggered by Ctrl-Alt-F9), but changes in imported modules are not. This is the
very behaviour of how Python imports work. If you want to make sure everything is in a fresh state,
click Restart UDF Server.
• The @[Link] decorator is only used by xlwings when the function is being imported into Excel. It
tells xlwings for which functions it should create a VBA wrapper function, otherwise it has no effect
on how the functions behave in Python.
Calling one big array formula in Excel is much more efficient than calling many single-cell formulas, so it’s
generally a good idea to use them, especially if you hit performance problems.
You can pass an Excel Range as a function argument, as opposed to a single cell and it will show up in
Python as list of lists.
For example, you can write the following function to add 1 to every cell in a Range:
@[Link]
def add_one(data):
return [[cell + 1 for cell in row] for row in data]
The above formula has the issue that it expects a “two dimensional” input, e.g. a nested list of the form [[1,
2], [3, 4]]. Therefore, if you would apply the formula to a single cell, you would get the following
error: TypeError: 'float' object is not iterable.
To force Excel to always give you a two-dimensional array, no matter whether the argument is a single cell,
a column/row or a two-dimensional Range, you can extend the above formula like this:
@[Link]
@[Link]('data', ndim=2)
def add_one(data):
return [[cell + 1 for cell in row] for row in data]
Often, you’ll want to use NumPy arrays or Pandas DataFrames in your UDF, as this unlocks the full power
of Python’s ecosystem for scientific computing.
To define a formula for matrix multiplication using numpy arrays, you would define the following function:
import xlwings as xw
import numpy as np
@[Link]
@[Link]('x', [Link], ndim=2)
@[Link]('y', [Link], ndim=2)
def matrix_mult(x, y):
return x @ y
Note: If you are not on Python >= 3.5 with NumPy >= 1.10, use [Link](y) instead of x @ y.
A great example of how you can put Pandas at work is the creation of an array-based CORREL formula.
Excel’s version of CORREL only works on 2 datasets and is cumbersome to use if you want to quickly
get the correlation matrix of a few time-series, for example. Pandas makes the creation of an array-based
CORREL2 formula basically a one-liner:
import xlwings as xw
import pandas as pd
@[Link]
@[Link]('x', [Link], index=False, header=False)
@[Link](index=False, header=False)
def CORREL2(x):
"""Like CORREL, but as array formula for more than 2 data sets"""
return [Link]()
These decorators are to UDFs what the options method is to Range objects: they allow you to apply
converters and their options to function arguments (@[Link]) and to the return value (@[Link]). For
example, to convert the argument x into a pandas DataFrame and suppress the index when returning it, you
would do the following:
@[Link]
@[Link]('x', [Link])
@[Link](index=False)
def myfunction(x):
# x is a DataFrame, do something with it
return x
Note: If your version of Excel supports the new native dynamic arrays, then you don’t have to do anything
special, and you shouldn’t use the expand decorator! To check if your version of Excel supports it, see if
you have the =UNIQUE() formula available. Native dynamic arrays were introduced in Office 365 Insider
Fast at the end of September 2018.
As seen above, to use Excel’s array formulas, you need to specify their dimensions up front by selecting the
result array first, then entering the formula and finally hitting Ctrl-Shift-Enter. In practice, it often
turns out to be a cumbersome process, especially when working with dynamic arrays such as time series
data. Since v0.10, xlwings offers dynamic UDF expansion:
This is a simple example that demonstrates the syntax and effect of UDF expansion:
import numpy as np
@[Link]
@[Link](expand='table')
def dynamic_array(r, c):
return [Link](int(r), int(c))
Note:
• Expanding array formulas will overwrite cells without prompting
• Pre v0.15.0 doesn’t allow to have volatile functions as arguments, e.g. you cannot use functions like
=TODAY() as arguments. Starting with v0.15.0, you can use volatile functions as input, but the UDF
will be called more than 1x.
• Dynamic Arrays have been refactored with v0.15.0 to be proper legacy arrays: To edit a dynamic
array with xlwings >= v0.15.0, you need to hit Ctrl-Shift-Enter while in the top left cell. Note
that you don’t have to do that when you enter the formula for the first time.
9.8 Docstrings
The following sample shows how to include docstrings both for the function and for the arguments x and y
that then show up in the function wizard in Excel:
import xlwings as xw
@[Link]
@[Link]('x', doc='This is x.')
@[Link]('y', doc='This is y.')
def double_sum(x, y):
"""Returns twice the sum of the two arguments"""
return 2 * (x + y)
You often need to know which cell called the UDF. For this, xlwings offers the reserved argument caller
which returns the calling cell as xlwings range object:
@[Link]
def get_caller_address(caller):
# caller will not be exposed in Excel, so use it like so:
(continues on next page)
Note that caller will not be exposed in Excel but will be provided by xlwings behind the scenes.
By using the vba keyword, you can get access to any Excel VBA object in the form of a pywin32 object.
For example, if you wanted to pass the sheet object in the form of its CodeName, you can do it as follows:
@[Link]
@[Link]('sheet1', vba='Sheet1')
def get_name(sheet1):
# call this function in Excel with:
# =get_name()
return [Link]
Note that vba arguments are not exposed in the UDF but automatically provided by xlwings.
9.11 Macros
On Windows, as an alternative to calling macros via RunPython, you can also use the @[Link] decorator:
import xlwings as xw
@[Link]
def my_macro():
"""Writes the name of the Workbook into Range("A1") of Sheet 1"""
wb = [Link]()
[Link][0].range('A1').value = [Link]
After clicking on Import Python UDFs, you can then use this macro by executing it via Alt + F8
or by binding it e.g. to a button. To do the latter, make sure you have the Developer tab selected under
File > Options > Customize Ribbon. Then, under the Developer tab, you can insert a button
via Insert > Form Controls. After drawing the button, you will be prompted to assign a macro to
it and you can select my_macro.
Imported functions can also be used from VBA. For example, for a function returning a 2d array:
Sub MySub()
arr = my_imported_function(...)
End Sub
import xlwings as xw
import time
@[Link](async_mode='threading')
def myfunction(a):
[Link](5) # long running tasks
return a
You can use this function like any other xlwings function, simply by putting =myfunction("abcd")
into a cell (after you have imported the function, of course).
Note that xlwings doesn’t use the native asynchronous functions that were introduced with Excel 2010, so
xlwings asynchronous functions are supported with any version of Excel.
10.1 Matplotlib
Note: If you set update=True, you can resize and position the plot on Excel: subsequent calls to
[Link]() with the same name ('MyPlot') will update the picture without changing its position
or size.
Calling the above code with RunPython and binding it e.g. to a button is straightforward and works cross-
platform.
37
xlwings - Make Excel Fly!, Release dev
However, on Windows you can make things feel even more integrated by setting up a UDF along the
following lines:
@[Link]
def myplot(n, caller):
fig = [Link]()
[Link](range(int(n)))
[Link](fig, name='MyPlot', update=True)
return 'Plotted with n={}'.format(n)
If you import this function and call it from cell B2, then the plot gets automatically updated when cell B1
changes:
10.1.3 Properties
Size, position and other properties can either be set as arguments within [Link](), or by manip-
ulating the picture object that is returned, see [Link]().
For example:
or:
10.1. Matplotlib 39
xlwings - Make Excel Fly!, Release dev
Here are a few examples of how you get a matplotlib figure object:
• via PyPlot interface:
or:
• via Pandas:
import pandas as pd
import numpy as np
10.2.1 Prerequisites
In addition to plotly you will need orca. The easiest way to get it is via conda:
It works the same as with Matplotlib, however, rendering a Plotly chart takes slightly longer. Here is a
sample:
import xlwings as xw
import [Link] as px
# Plotly chart
df = [Link]()
fig = [Link](df, x="sepal_width", y="sepal_length", color="species")
# Add it to Excel
wb = [Link]()
[Link][0].[Link](fig, name='IrisScatterPlot', update=True)
When you work with Jupyter notebooks, you may use Excel as an interactive data viewer or scratchpad from
where you can load DataFrames. The two convenience functions view and load make this really easy.
Note: The view and load functions should exclusively be used for interactive work. If you write scripts,
use the xlwings API as introduced under Quickstart and Syntax Overview.
The view function accepts pretty much any object of interest, whether that’s a number, a string, a nested
list or a NumPy array or a pandas DataFrame. By default, it writes the data into an Excel table in a
new workbook. If you wanted to reuse the same workbook, provide a sheet object, e.g. view(df,
sheet=[Link]), for further options see view.
Changed in version 0.22.0: Earlier versions were not formatting the output as Excel table
To load in a range in an Excel sheet as pandas DataFrame, use the load function. If you only select one
cell, it will auto-expand to cover the whole range. If, however, you select a specific range that is bigger than
one cell, it will load in only the selected cells. If the data in Excel does not have an index or header, set them
to False like this: [Link](index=False), see also load.
New in version 0.22.0.
43
xlwings - Make Excel Fly!, Release dev
xlwings comes with a command line client. On Windows, type the commands into a Command Prompt,
on Mac, type them into a Terminal. To get an overview of all commands, simply type xlwings and hit
Enter:
addin Run "xlwings addin install" to install the Excel add-
in (will be copied to the XLSTART folder). Instead of
"install" you can also use "update", "remove" or
"status". Note that this command may take a while. Use
the "--unprotected" flag to install the add-in without
password protection. You can install your custom add-
in by providing the name or path via the --file flag,
e.g. "xlwings add-in install --file [Link]"
(New in 0.6.0, the unprotected flag was added in 0.20.4)
quickstart Run "xlwings quickstart myproject" to create a folder
called "myproject" in the current directory with an
Excel file and a Python file, ready to be used. Use
the "--standalone" flag to embed all VBA code in the
Excel file and make it work without the xlwings add-
in.
runpython macOS only: run "xlwings runpython install" if you
want to enable the RunPython calls without installing
the add-in. This will create the following file:
~/Library/Application
Scripts/[Link]/[Link]
(new in 0.7.0)
restapi Use "xlwings restapi run" to run the xlwings REST API
via Flask dev server. Accepts "--host" and "--port" as
optional arguments.
license xlwings PRO: Use "xlwings license update -k KEY" where
"KEY" is your personal (trial) license key. This will
update ~/.xlwings/[Link] with the LICENSE_KEY
(continues on next page)
45
xlwings - Make Excel Fly!, Release dev
xlwings Reports
13.1 Quickstart
xlwings Reports is part of xlwings PRO and a solution for template-based Excel and PDF reporting. It
allows business users without Python knowledge to create & maintain Excel templates without having to
go back to a Python developer for every change: xlwings Reports separates the Python code (that gets and
prepares all the data) from the Excel template (that defines which data goes where and how it should be
formatted). See also the xlwings Reports homepage. You can render one sheet at the time via mysheet.
render_template or use the higher-level convenience function xw.create_report which first
copies the template workbook and then loops through all sheets.
Let’s first look at how to render a single sheet. This is a workbook stored as [Link]:
Running the following code:
import xlwings as xw
wb = [Link]('[Link]')
sheet = [Link]['template'].copy(name='report')
sheet.render_template(title='A Demo!', table=[[1, 2], [3, 4]])
wb.to_pdf() # requires xlwings >=0.21.1
47
xlwings - Make Excel Fly!, Release dev
If your template is a full workbook, you can use the create_report function. Start by creating the
following Python script my_template.py:
df = [Link](data=[[1,2],[3,4]])
wb = create_report('my_template.xlsx', 'my_report.xlsx', title='MyTitle',
˓→df=df)
python my_template.py
This will copy the template and create the following output by replacing the variables in double curly braces
with the value from the Python variable:
The last line (wb.to_pdf()) will print the workbook as PDF, for more details on the options, see Book.
to_pdf().
Apart from Strings and Pandas DataFrames, you can also use numbers, lists, simple dicts, NumPy arrays,
Matplotlib figures and PIL Image objects that have a filename.
13.1. Quickstart 49
xlwings - Make Excel Fly!, Release dev
By default, xlwings Reports overwrites existing values in templates if there is not enough free space for your
variable. If you want your rows to dynamically shift according to the height of your array, use Frames.
See also the API reference.
13.2 Frames
Frames are vertical containers in which content is being aligned according to their height. That is, within
Frames:
• Variables do not overwrite existing cell values as they do without Frames.
• Formatting is applied dynamically, depending on the number of rows your object uses in Excel
To use Frames, insert <frame> into row 1 of your Excel template wherever you want a new dyanmic
column to start. Row 1 will be removed automatically when creating the report. Frames go from one
<frame> to the next <frame> or the right border of the used range.
How Frames behave is best demonstrated with an example: The following screenshot defines two frames.
The first one goes from column A to column E and the second one goes from column F to column I, since
this is the last column that is used.
You can define and format table-like objects by formatting exactly
• one header and
• one data row
as shown in the screenshot:
However, also make sure to check out how to use Excel Tables below, as they make the formatting easier.
Running the following code:
create_report('my_template.xlsx',
'my_report.xlsx',
**data)
Using Excel tables is the recommended way to format tables as the styling can be applied dynamically
across columns and rows. You can also use themes and apply alternating colors to rows/columns. On top of
that, they are the easiest way to make the source of a chart dynamic. Go to Insert > Table and make
sure that you activate My table has headers before clicking on OK. Add the placeholder as usual on
the top-left of your Excel table:
Running the following script:
nrows, ncols = 3, 3
df = [Link](data=nrows * [ncols * ['test']],
columns=['col ' + str(i) for i in range(ncols)])
Note:
• If you would like to exclude the DataFrame index, make sure to set the index to the first column e.g.:
df.set_index('column_name').
Note: To use charts with a dynamic source, you’ll need at least xlwings version 0.22.1
To use Excel charts in your reports, follow this process:
1. Add some sample/dummy data to your Excel template:
2. If your data source is dynamic, turn it into an Excel Table (Insert > Table). Make sure you do
this before adding the chart in the next step.
4. Reduce the Excel table to a 2 x 2 range and add the placeholder in the top-left corner (in our example
chart_data) . You can leave in some dummy data or clear the values of the Excel table:
5. Assuming your file is called [Link] and your sheet template like on the previous
screenshot, you can run the following code:
import xlwings as xw
import pandas as pd
wb = [Link]("[Link]")
sheet = [Link]['template'].copy(name='report')
sheet.render_template(chart_data=df)
This will produce the following report, with the chart source correctly adjusted:
Note: If you don’t want the source data on your report, you might want to place it on a separate sheet. It’s
easiest if you add and design the chart on the separate sheet, before cutting the chart and pasting it on your
report template.
Deployment
PYTHONPATH, "C:\path\to\[Link]"
14.2 RunFrozenPython
Note:
• This does not work with UDFs.
• Currently only available on Windows, but support for Mac should be easy to add.
59
xlwings - Make Excel Fly!, Release dev
• You need at least 0.15.2 to support arguments whereas the syntax changed in 0.15.6
Use it as follows:
Sub MySample()
RunFrozenPython "C:\path\to\dist\myproject\[Link]", "arg1 arg2"
End Sub
Sub RandomNumbers()
RunPython ("import random_numbers;random_numbers.main()")
End Sub
Note: UDFs modules don’t have to be added to the UDF Modules explicitly when using embedded code.
However, in contrast to how it works with external files, you currently need to re-import the functions when
you change them.
Note: While you can hide your sheets with your code, they will be written to a temporary directory in clear
text.
• Installing
Give the end user your Excel workbook and the installer. The user only has to double-click the
installer and confirm a few prompts — no configuration is required.
• Updating
If you use the embedded code feature (see: Embedded Code), you can deploy updates by simply
giving the user a new Excel file. Only when you change a dependency, you will need to create a new
installer.
• Uninstalling
The application can be uninstalled again via Windows Settings > Apps & Features.
Before you can build the installer, the project needs to be configured correctly, see below.
In the GitHub repo, go to x releases > Draft/Create a new release. Add a version like 1.
0.0 to Tag version, then hit Publish release.
Wait a few minutes and refresh the page: the installer will appear under the release from where you can
download it. You can follow the progress under the Actions tab.
14.4.3 Configuration
Excel file
You can add your Excel file to the repository if you like but it’s not a requirement. Configure the Excel file
as follows:
• Add the standalone xlwings VBA module, e.g. via xlwings quickstart project
--standalone
• Make sure that in the VBA editor (Alt-F11) under Tools > References xlwings is unchecked
• Rename the _xlwings.conf sheet into [Link]
xlwings==0.18.0
numpy==1.18.2
PROJECT:
APP_PUBLISHER:
Python version
Set your Python version under .github/[Link]:
python-version: '3.7'
architecture: 'x64'
Note: You need a paid developer license to generate a deployment key. A trial license won’t work.
Then paste the generated key into the xlwings config as LICENSE_KEY. For deployment purposes, usually
the best place to do that is on a sheet called [Link], but you can also use an [Link] file
in either the same folder or in the .xlwings folder within the user’s home folder. To use an environment
variable, use XLWINGS_LICENSE_KEY. See also User Settings.
Troubleshooting
Solution:
1) xlwings32-<version>.dll and xlwings64-<version>.dll are both in the same direc-
tory as your [Link]. If not, something went wrong with your installation. Reinstall it with
pip or conda, see Installation.
2) Check your Interpreter in the add-in or config sheet. If it is empty, then you need to be
able to open a windows command prompt and type python to start an interactive Python session.
If you get the error 'python' is not recognized as an internal or external
command, operable program or batch file., then you have two options: Either add
the path of where your [Link] lives to your Windows path (see [Link]
com/issues/[Link]) or set the full path to your interpreter in the add-in or your config sheet,
e.g. C:\Users\MyUser\anaconda\[Link]
Solution:
On either the [Link] sheet or on the [Link] file under your home folder (for location
see User Config: Ribbon/Config File), add the following setting:
"ONEDRIVE", "C:\path\to\OneDrive"
65
xlwings - Make Excel Fly!, Release dev
xlwings PRO
The purpose of xlwings PRO is to finance the continued maintenance and enhancement of xlwings. This
will allow you to rely on the package without being left with the dreaded “this library currently has no active
maintainers” message that happens to too many open-source packages after a couple of years.
xlwings PRO offers access to additional functionality. All PRO features are marked with xlwings PRO in
the docs.
Note: To get access to the additional functionality of xlwings PRO, you need a license key and at least xl-
wings v0.19.0. Everything under the [Link] subpackage is distributed under a commercial license.
• [Link](): An easy way to keep an Excel table in sync with a pandas DataFrame
• Embedded Code: Store your Python source code directly in Excel for easy deployment.
• xlwings Reports: A template based reporting mechanism, allows business users to change the layout
of the report without having to change Python code.
• Plotly static charts: Support for Plotly static charts.
• One-Click Zero-Config Installer: Guarantees that the end user does not need to know anything about
Python.
67
xlwings - Make Excel Fly!, Release dev
• Pricing: [Link]
• Trial license key: [Link]
Introduced with v0.7.0, converters define how Excel ranges and their values are converted both during
reading and writing operations. They also provide a consistent experience across [Link] objects
and User Defined Functions (UDFs).
Converters are explicitly set in the options method when manipulating Range objects or in the @[Link]
and @[Link] decorators when using UDFs. If no converter is specified, the default converter is applied
when reading. When writing, xlwings will automatically apply the correct converter (if available) according
to the object’s type that is being written to Excel. If no converter is found for that type, it falls back to the
default converter.
All code samples below depend on the following import:
Syntax:
[Link] UDFs
read- [Link](convert=None, @arg('x',
ing **kwargs).value convert=None,
**kwargs)
writ- [Link](convert=None, @ret(convert=None,
ing **kwargs).value = myvalue **kwargs)
Note: Keyword arguments (kwargs) may refer to the specific converter or the default converter. For
example, to set the numbers option in the default converter and the index option in the DataFrame
converter, you would write:
69
xlwings - Make Excel Fly!, Release dev
• numbers
By default cells with numbers are read as float, but you can change it to int:
>>> [Link]('A1').value = 1
>>> [Link]('A1').value
1.0
>>> [Link]('A1').options(numbers=int).value
1
Alternatively, you can specify any other function or type which takes a single float argument.
Using this on UDFs looks like this:
@[Link]
@[Link]('x', numbers=int)
def myfunction(x):
(continues on next page)
Note: Excel always stores numbers internally as floats, which is the reason why the int converter
rounds numbers first before turning them into integers. Otherwise it could happen that e.g. 5 might be
returned as 4 in case it is represented as a floating point number that is slightly smaller than 5. Should
you require Python’s original int in your converter, use raw int instead.
• dates
By default cells with dates are read as [Link], but you can change it to datetime.
date:
– Range:
• empty
Empty cells are converted per default into None, you can change this as follows:
– Range: >>> [Link]('A1').options(empty='NA').value
– UDFs: @[Link]('x', empty='NA')
• transpose
This works for reading and writing and allows us to e.g. write a list in column orientation to Excel:
– Range: [Link]('A1').options(transpose=True).value = [1, 2, 3]
– UDFs:
@[Link]('x', transpose=True)
@[Link](transpose=True)
def myfunction(x):
# x will be returned unchanged as transposed both when reading
˓→and writing
return x
• expand
This works the same as the Range properties table, vertical and horizontal but is only
evaluated when getting the values of a Range:
Note: The expand method is only available on Range objects as UDFs only allow to manipulate
the calling cells.
xlwings offers several built-in converters that perform type conversion to dictionaries, NumPy arrays,
Pandas Series and DataFrames. These build on top of the default converter, so in most cases the options
described above can be used in this context, too (unless they are meaningless, for example the ndim in the
case of a dictionary).
It is also possible to write and register a custom converter for additional types, see below.
The samples below can be used with both [Link] objects and UDFs even though only one
version may be shown.
The dictionary converter turns two Excel columns into a dictionary. If the data is in row orientation, use
transpose:
Note: instead of dict, you can also use OrderedDict from collections.
# Writing back and changing some of the options, e.g. getting rid of the
˓→index:
>>> [Link]('B7').options(index=False).value = df
The same sample for UDF (starting in Range('A13') on screenshot) looks like this:
@[Link]
@[Link]('x', [Link], header=2)
@[Link](index=False)
def myfunction(x):
# x is a DataFrame, do something with it
return x
@[Link]
@[Link]('x', 'range')
def myfunction(x):
return [Link]
This returns x as [Link] object, i.e. without applying any converters or options.
• The raw converter delivers the values unchanged from the underlying libraries (pywin32 on Win-
dows and appscript on Mac), i.e. no sanitizing/cross-platform harmonizing of values are being
made. This might be useful in a few cases for efficiency reasons. E.g:
>>> [Link]('A1:B2').value
[[1.0, 'text'], [[Link](2016, 2, 1, 0, 0), None]]
class MyConverter(Converter):
@staticmethod
def read_value(value, options):
myoption = [Link]('myoption', default_value)
return_value = value # Implement your conversion here
return return_value
@staticmethod
def write_value(value, options):
myoption = [Link]('myoption', default_value)
return_value = value # Implement your conversion here
return return_value
• Optional: set a base converter (base expects a class name) to build on top of an ex-
isting converter, e.g. for the built-in ones: DictCoverter, NumpyArrayConverter,
PandasDataFrameConverter, PandasSeriesConverter
• Optional: register the converter: you can (a) register a type so that your converter becomes the default
for this type during write operations and/or (b) you can register an alias that will allow you to explicitly
call your converter by name instead of just by class name
The following examples should make it much easier to follow - it defines a DataFrame converter that extends
the built-in DataFrame converter to add support for dropping nan’s:
class DataFrameDropna(Converter):
base = PandasDataFrameConverter
@staticmethod
def read_value(builtin_df, options):
dropna = [Link]('dropna', False) # set default to False
if dropna:
converted_df = builtin_df.dropna()
else:
converted_df = builtin_df
(continues on next page)
@staticmethod
def write_value(df, options):
dropna = [Link]('dropna', False)
if dropna:
converted_df = [Link]()
else:
converted_df = df
# This will be passed to the built-in PandasDataFrameConverter when
˓→writing
return converted_df
# Write
[Link]('A1').value = df
# Read
[Link]('A1:C4').options([Link]).value
• DataFrameDropna converter:
# Write
[Link]('A7').options(DataFrameDropna, dropna=True).value = df
# Read
[Link]('A1:C4').options(DataFrameDropna, dropna=True).value
[Link]('df_dropna')
# Write
[Link]('A12').options('df_dropna', dropna=True).value = df
# Read
[Link]('A1:C4').options('df_dropna', dropna=True).value
[Link]([Link])
# Read
[Link]('A1:C4').options([Link], dropna=True).value
@[Link]
@arg('x', DataFrameDropna, dropna=True)
@ret(DataFrameDropna, dropna=True)
def myfunction(x):
# ...
return x
Note: Python objects run through multiple stages of a transformation pipeline when they are being written
to Excel. The same holds true in the other direction, when Excel/COM objects are being read into Python.
Pipelines are internally defined by Accessor classes. A Converter is just a special Accessor which converts
to/from a particular type by adding an extra stage to the pipeline of the default Accessor. For example, the
PandasDataFrameConverter defines how a list of lists (as delivered by the default Accessor) should
be turned into a Pandas DataFrame.
The Converter class provides basic scaffolding to make the task of writing a new Converter easier. If you
need more control you can subclass Accessor directly, but this part requires more work and is currently
undocumented.
Debugging
Since xlwings runs in every Python environment, you can use your preferred way of debugging.
• RunPython: When calling Python through RunPython, you can set a mock_caller to make it
easy to switch back and forth between calling the function from Excel and Python.
• UDFs: For debugging User Defined Functions, xlwings offers a convenient debugging server
To begin with, Excel will show Python errors in a Message Box:
Note: On Mac, if the import of a module/package fails before xlwings is imported, the popup will
81
xlwings - Make Excel Fly!, Release dev
not be shown and the StatusBar will not be reset. However, the error will still be logged in the log file
(/Users/<User>/Library/Containers/[Link]/Data/[Link]).
18.1 RunPython
Consider the following sample code of your Python source code my_module.py:
# my_module.py
import os
import xlwings as xw
def my_macro():
wb = [Link]()
[Link][0].range('A1').value = 1
if __name__ == '__main__':
# Expects the Excel file next to this source file, adjust accordingly.
[Link]('[Link]').set_mock_caller()
my_macro()
my_macro() can now easily be run from Python for debugging and from Excel via RunPython without
having to change the source code:
Sub my_macro()
RunPython "import my_module; my_module.my_macro()"
End Sub
Windows only: To debug UDFs, just check the Debug UDFs in the Add-in & Settings, at the top of
the xlwings VBA module. Then add the following lines at the end of your Python source file and run it.
Depending on which IDE you use, you might need to run the code in “debug” mode (e.g. in case you’re
using PyCharm or PyDev):
if __name__ == '__main__':
[Link]()
When you recalculate the Sheet (Ctrl-Alt-F9), the code will stop at breakpoints or output any print calls
that you may have.
The following screenshot shows the code stopped at a breakpoint in the community version of PyCharm:
Note: When running the debug server from a command prompt, there is currently no gracious way to
terminate it, but closing the command prompt will kill it.
Extensions
It’s easy to extend the xlwings add-in with own code like UDFs or RunPython macros, so that they can
be deployed without end users having to import or write the functions themselves. Just add another VBA
module to the xlwings addin with the respective code.
UDF extensions can be used from every workbook without having to set a reference.
The xlwings addin comes with a built-in extension that adds in-Excel SQL syntax (sqlite dialect):
As this extension uses UDFs, it’s only available on Windows right now.
85
xlwings - Make Excel Fly!, Release dev
Custom Add-ins
20.1 Quickstart
Start by running the following command on a command line (to create an add-in without a ribbon, you
would leave away the --ribbon flag):
This will create the familiar quickstart folder with a Python file and an Excel file, but this time, the Excel
file is in the xlam format.
• Double-click the Excel add-in to open it in Excel
• Add a new empty workbook (Ctrl+N on Windows or Command+N on macOS)
You should see a new ribbon tab called MyAddin like this:
The add-in and VBA project are currently always called myaddin, no matter what name you chose in the
quickstart command. We’ll see towards the end of this tutorial how we can change that, but for now we’ll
stick with it.
87
xlwings - Make Excel Fly!, Release dev
Compared to the xlwings add-in, the custom add-in offers an additional level of configuration: the configura-
tion sheet of the add-in itself which is the easiest way to configure simple add-ins with a static configuration.
Let’s open the VBA editor by clicking on Alt+F11 (Windows) or Option+F11 (macOS). In our project,
select ThisWorkbook, then change the Property IsAddin from True to False, see the following
screenshot:
This will make the sheet _myaddin.conf visible (again, we’ll see how to change the name of myaddin
at the end of this tutorial):
• Activate the sheet config by renaming it from _myaddin.conf to [Link]
• Set your Interpreter_Win/_Mac or Conda settings (you may want to take them over from the
xlwings settings for now)
Once done, switch back to the VBA editor, select ThisWorkbook again, and change IsAddin back to
True before you save your add-in from the VBA editor. Switch back to Excel and click the Run button
under the My Addin ribbon tab and if you’ve configured the Python interpreter correctly, it will print
Hello xlwings! into cell A1 of the active workbook.
To change the buttons and items in the ribbon menu or the Backstage View, download and install the Office
RibbonX Editor. While it is only available for Windows, the created ribbons will also work on macOS. Open
your add-in with it so you can change the XML code that defines your buttons etc. You will find a good
tutorial here. The callback function for the demo Run button is in the RibbonMyAddin VBA module that
you’ll find in the VBA editor.
To import your UDFs into the custom add-in, run the ImportPythonUDFsToAddin Sub towards the
end of the xlwings module (click into the Sub and hit F5). Remember, you only have to do this whenever
you change the function name, argument or decorator, so you’re end users won’t have to deal with this.
If you are only deploying UDFs via your add-in, you probably don’t need a Ribbon menu and can leave
away the --ribbon flag in the quickstart command.
20.4 Configuration
As mentioned before, configuration works the same as with xlwings, so you could have your users override
the default configuration we did above by adding a [Link] sheet on their workbook or you could
use the [Link] file in the user’s home directory. For details see Add-in & Settings.
20.5 Installation
If you want to permanently install your add-in, you can do so by using the xlwings CLI:
This, however, means that you will need to adjust the PYTHONPATH for it to find your Python code (or move
your Python code to somewhere where Python looks for it—more about that below under deployment). The
command will copy your add-in to the XLSTART folder, a special folder from where Excel will open all
files everytime you start it.
Admittedly, this part is a bit cumbersome for now. Let’s assume, we would like to rename the addin from
MyAddin to Demo:
• In the xlwings VBA module, change Public Const PROJECT_NAME As String =
"myaddin" to Public Const PROJECT_NAME As String = "demo". You’ll find this
line at the top, right after the Declare statements.
• If you rely on the [Link] sheet for your configuration, rename it to [Link]
• Right-click the VBA project, select MyAddin Properties... and rename the Project Name
from MyAddin to Demo.
• If you use the ribbon, you want to rename the RibbonMyAddin VBA module to RibbonDemo.
To do this, select the module in the VBA editor, then rename it in the Properties window. If you
don’t see the Properties window, hit F4.
• Open the add-in in the Office RibbonX Editor (see above) and replace all occurrences of MyAddin
with Demo in the XML code.
And finally, you may want to rename your [Link] file in the Windows explorer, but I assume
you have already run the quickstart command with the correct name, so this won’t be necessary.
20.7 Deployment
By far the easiest way to deploy your add-in to your end-users is to build an installer via the xlwings PRO
offering. This will take care of everything and your end users literally just need to double-click the installer
and they are all set (no existing Python installation required and no manual installation of the add-in or
adjusting of settings required).
If you want it the free (but hard) way, you either need to build an installer yourself or you need your users to
install Python and the add-in and take care of placing the Python code in the correct directory. This normally
involves tweaking the following settings, for example in the [Link] sheet:
• Interpreter_Win/_Mac: if your end-users have a working version of Python, you can use en-
vironment variables to dynamically resolve to the correct path. For example, if they have Anaconda
installed in the default location, you could use the following configuration:
• PYTHONPATH: since you can’t have your Python source code in the XLSTART folder next to the
add-in, you’ll need to adjust the PYTHONPATH setting and add the folder to where the Python code
will be. You could point this to a shared drive or again make use of environment variables so the
users can place the file into a folder called MyAddin in their home directory, for example. However,
you can also place your Python code where Python looks for it, for example by placing them in the
site-packages directory of the Python distribution—an easy way to achieve this is to build a
Python package that you can install via pip.
20.7. Deployment 91
xlwings - Make Excel Fly!, Release dev
21.1 Threading
While xlwings is not technically thread safe, it’s still easy to use it in threads as long as you have at least
v0.13.0 and stick to a simple rule: Do not pass xlwings objects to threads. This rule isn’t a requirement on
macOS, but it’s still recommended if you want your programs to be cross-platform.
Consider the following example that will NOT work:
import threading
from queue import Queue
import xlwings as xw
num_threads = 4
def write_to_workbook():
while True:
rng = [Link]()
[Link] = [Link]
print([Link])
q.task_done()
q = Queue()
for i in range(num_threads):
t = [Link](target=write_to_workbook)
(continues on next page)
93
xlwings - Make Excel Fly!, Release dev
for cell in ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10']:
# THIS DOESN'T WORK - passing xlwings objects to threads will fail!
rng = [Link]('[Link]').sheets[0].range(cell)
[Link](rng)
[Link]()
To make it work, you simply have to fully qualify the cell reference in the thread instead of passing a Book
object:
import threading
from queue import Queue
import xlwings as xw
num_threads = 4
def write_to_workbook():
while True:
cell_ = [Link]()
[Link]('[Link]').sheets[0].range(cell_).value = cell_
print(cell_)
q.task_done()
q = Queue()
for i in range(num_threads):
t = [Link](target=write_to_workbook)
[Link] = True
[Link]()
for cell in ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10']:
[Link](cell)
[Link]()
21.2 Multiprocessing
The same rules apply to multiprocessing as for threading, here’s a working example:
def write_to_workbook(cell):
[Link]('[Link]').sheets[0].range(cell).value = cell
print(cell)
if __name__ == '__main__':
with Pool(4) as p:
[Link](write_to_workbook,
['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10'])
21.2. Multiprocessing 95
xlwings - Make Excel Fly!, Release dev
Missing Features
This works accordingly for the other objects like [Link]('A1').api etc.
The underlying objects will offer you pretty much everything you can do with VBA, using the syntax
of pywin32 (which pretty much feels like VBA) and appscript (which doesn’t feel like VBA). But
apart from looking ugly, keep in mind that it makes your code platform specific (!), i.e. even if you
go for option 2), you should still follow option 1) and open an issue so the feature finds it’s way into
the library (cross-platform and with a Pythonic syntax).
# Windows
[Link]('A1').[Link] = True
# Mac
[Link]('A1').api.wrap_text.set(True)
97
xlwings - Make Excel Fly!, Release dev
xlwings can also be used to call Python functions from VBA within Office apps other than Excel (like
Outlook, Access etc.).
Note: New in v0.12.0 and still in a somewhat early stage that involves a bit of manual work. Currently,
this functionality is only available on Windows for UDFs. The RunPython functionality is currently not
supported.
23.1 How To
1) As usual, write your Python function and import it into Excel (see User Defined Functions (UDFs)).
2) Press Alt-F11 to get into the VBA editor, then right-click on the xlwings_udfs VBA module
and select Export File.... Save the xlwings_udfs.bas file somewhere.
3) Switch into the other Office app, e.g. Microsoft Access and click again Alt-F11 to get into the
VBA editor. Right-click on the VBA Project and Import File..., then select the file that you
exported in the previous step. Once imported, replace the app name in the first line to the one that
you are using, i.e. Microsoft Access or Microsoft Outlook etc. so that the first line then
reads: #Const App = "Microsoft Access"
4) Now import the standalone xlwings VBA module ([Link]). You can find it in your xlwings
installation folder. To know where that is, do:
99
xlwings - Make Excel Fly!, Release dev
And finally do the same as in the previous step and replace the App name in the first line with the
name of the corresponding app that you are using. You are now able to call the Python function from
VBA.
23.2 Config
The other Office apps will use the same global config file as you are editing via the Excel ribbon add-
in. When it makes sense, you’ll be able to use the directory config file (e.g. you can put it next to your
Access or Word file) or you can hardcode the path to the config file in the VBA standalone module, e.g. in
the function GetDirectoryConfigFilePath (e.g. suggested when using Outlook that doesn’t really
have the same concept of files like the other Office apps). NOTE: For Office apps without file concept, you
need to make sure that the PYTHONPATH points to the directory with the Python source file. For details on
the different config options, see Config.
While xlwings is a pure Python package, there are cross-language packages that allow for a relatively
straightforward use from/with other languages. This means, however, that you’ll always need to have
Python with xlwings installed in addition to R or Julia. We recommend the Anaconda distribution, see
also Installation.
24.1 R
The R instructions are for Windows, but things work accordingly on Mac except that calling the R functions
as User Defined Functions is not supported at the moment (but RunPython works, see Call Python with
“RunPython”).
Setup:
• Install R and Python
• Add R_HOME environment variable to base directory of installation, .e.g C:\Program
Files\R\R-x.x.x
• Add R_USER environment variable to user folder, e.g. C:\Users\<user>
• Add C:\Program Files\R\R-x.x.x\bin to PATH
• Restart Windows because of the environment variables (!)
101
xlwings - Make Excel Fly!, Release dev
@[Link]
def myfunction(x, y):
myfunc = robjects.r['myfunction']
return tuple(myfunc(x, y))
After importing this function (see: User Defined Functions (UDFs)), it will be available as UDF from Excel.
[Link](r"C:\path\to\r_file.R")
[Link]()
@[Link]
@[Link]("x", [Link], ndim=2)
@[Link]("y", [Link], ndim=2)
def array_function(x, y):
array_func = robjects.r['array_function']
return [Link](array_func(x, y))
After importing this function (see: User Defined Functions (UDFs)), it will be available as UDF from Excel.
24.2 Julia
Setup:
julia> [Link]()
PyObject <Book [Workbook1]>
Python API
Examples
105
xlwings - Make Excel Fly!, Release dev
[Link](index=1, header=1)
Loads the selected cell(s) of the active workbook into a pandas DataFrame. If you select a single cell
that has adjacent cells, the range is auto-expanded and turned into a pandas DataFrame. If you don’t
have pandas installed, it returns the values as nested lists.
Parameters
• index (bool or int, default 1) – Defines the number of columns on
the left that will be turned into the DataFrame’s index
• header (bool or int, default 1) – Defines the number of rows at the
top that will be turned into the DataFrame’s columns
Examples
25.2.1 Apps
class [Link](impl)
A collection of all app objects:
active
Returns the active app.
New in version 0.9.0.
add()
Creates a new App. The new App becomes the active one. Returns an App object.
count
Returns the number of apps.
New in version 0.9.0.
keys()
Provides the PIDs of the Excel instances that act as keys in the Apps collection.
New in version 0.13.0.
25.2.2 App
>>> [Link]
Apps([<Excel App 1668>, <Excel App 1644>])
>>> [Link][1668] # get the available PIDs via [Link]()
<Excel App 1668>
>>> [Link]
<Excel App 1668>
Parameters
• visible (bool, default None) – Returns or sets a boolean value that
determines whether the app is visible. The default leaves the state unchanged or
sets visible=True if the object doesn’t exist yet.
• spec (str, default None) – Mac-only, use the full path to the Excel appli-
cation, e.g. /Applications/Microsoft Office 2011/Microsoft
Excel or /Applications/Microsoft Excel
On Windows, if you want to change the version of Excel that xlwings talks to, go
to Control Panel > Programs and Features and Repair the Of-
fice version that you want as default.
Note: On Mac, while xlwings allows you to run multiple instances of Excel, it’s a feature that is
not officially supported by Excel for Mac: Unlike on Windows, Excel will not ask you to open a
read-only version of a file if it is already open in another instance. This means that you need to watch
out yourself so that the same file is not being overwritten from different instances.
activate(steal_focus=False)
Activates the Excel app.
Parameters steal_focus (bool, default False) – If True, make front-
most application and hand over focus from Python to Excel.
New in version 0.9.0.
api
Returns the native object (pywin32 or appscript obj) of the engine being used.
New in version 0.9.0.
books
A collection of all Book objects that are currently open.
New in version 0.9.0.
calculate()
Calculates all open books.
New in version 0.3.6.
calculation
Returns or sets a calculation value that represents the calculation mode. Modes: 'manual',
'automatic', 'semiautomatic'
Examples
Examples
Function MySum(x, y)
MySum = x + y
End Function
Examples
25.2.3 Books
class [Link](impl)
A collection of all book objects:
25.2.4 Book
The easiest way to connect to a book is offered by [Link]: it looks for the book in all app instances
and returns an error, should the same book be open in multiple instances. To connect to a book in the
active app instance, use [Link] and to refer to a specific app, use:
[Link] [Link]
New book [Link]() [Link]()
Unsaved book [Link]('Book1') [Link]['Book1']
Book by [Link](r'C:/path/to/ [Link](r'C:/path/to/
(full)name [Link]') [Link]')
Parameters
• fullname (str or path-like object, default None) – Full path
or name (incl. xlsx, xlsm etc.) of existing workbook or name of an unsaved work-
book. Without a full path, it looks for the file in the current working directory.
• update_links (bool, default None) – If this argument is omitted, the
user is prompted to specify how links will be updated
• read_only (bool, default False) – True to open workbook in read-
only mode
• format (str) – If opening a text file, this specifies the delimiter character
• password (str) – Password to open a protected workbook
• write_res_password (str) – Password to write to a write-reserved work-
book
• ignore_read_only_recommended (bool, default False) – Set to
True to mute the read-only recommended message
• origin (int) – For text files only. Specifies where it originated. Use XlPlat-
form constants.
activate(steal_focus=False)
Activates the book.
Parameters steal_focus (bool, default False) – If True, make front-
most window and hand over focus from Python to Excel.
api
Returns the native object (pywin32 or appscript obj) of the engine being used.
New in version 0.9.0.
app
Returns an app object that represents the creator of the book.
New in version 0.9.0.
classmethod caller()
References the calling book when the Python function is called from Excel via RunPython.
Pack it into the function being called from Excel, e.g.:
import xlwings as xw
def my_macro():
wb = [Link]()
[Link][0].range('A1').value = 1
To be able to easily invoke such code from Python for debugging, use [Link].
set_mock_caller().
New in version 0.3.0.
close()
Closes the book without saving it.
New in version 0.1.1.
fullname
Returns the name of the object, including its path on disk, as a string. Read-only String.
macro(name)
Runs a Sub or Function in Excel VBA.
Parameters name (Name of Sub or Function with or without module name, e.g.
'[Link]' or 'MyMacro') –
Examples
Example
Examples
# This code runs unchanged from Excel via RunPython and from Python
˓→directly
import os
import xlwings as xw
def my_macro():
sht = [Link]().sheets[0]
[Link]('A1').value = 'Hello xlwings!'
if __name__ == '__main__':
[Link]('[Link]').set_mock_caller()
my_macro()
Examples
>>> wb = [Link]()
>>> [Link][0]['A1'].value = 'PDF'
>>> wb.to_pdf()
25.2.5 Sheets
class [Link](impl)
A collection of all sheet objects:
25.2.6 Sheet
Examples
Parameters
• before (sheet object, default None) – The sheet object before
which you want to place the sheet
• after (sheet object, default None) – The sheet object after which
you want to place the sheet, by default it is placed after all existing sheets
• name (str, default None) – The sheet name of the copy
Returns Sheet object – The copied sheet
Return type Sheet
Examples
delete()
Deletes the Sheet.
index
Returns the index of the Sheet (1-based as in Excel).
name
Gets or sets the name of the Sheet.
names
Returns a names collection that represents all the sheet-specific names (names defined with the
“SheetName!” prefix).
New in version 0.9.0.
pictures
See Pictures
New in version 0.9.0.
range(cell1, cell2=None)
Returns a Range object from the active sheet of the active book, see Range().
New in version 0.9.0.
render_template(**data)
This method requires xlwings PRO.
Replaces all Jinja variables (e.g {{ myvar }}) in the sheet with the keyword argument that
has the same name. Following variable types are supported:
strings, numbers, lists, simple dicts, NumPy arrays, Pandas DataFrames, PIL Image objects that
have a filename and Matplotlib figures.
New in version 0.22.0.
Parameters data (kwargs) – All key/value pairs that are used in the template.
Returns sheet
Return type xlwings Sheet
Examples
25.2.7 Range
Examples
Active Sheet:
import xlwings as xw
[Link]('A1')
[Link]('A1:C3')
[Link]((1,1))
[Link]((1,1), (3,3))
[Link]('NamedRange')
[Link]([Link]('A1'), [Link]('B2'))
Specific Sheet:
[Link]['[Link]'].sheets[0].range('A1')
clear_contents()
Clears the content of a Range but leaves the formatting.
color
Gets and sets the background color of the specified Range.
To set the color, either use an RGB tuple (0, 0, 0) or a color constant. To remove the
background, set the color to None, see Examples.
Returns RGB
Return type tuple
Examples
Examples
Examples
Examples
Examples
Returns
Return type None
last_cell
Returns the bottom right cell of the specified range. Read-only.
Returns
Return type Range
Example
Examples
Note: If the Range is outside the used range of the Worksheet, and rows in the Range have
different heights, returns the height of the first row.
Returns
Return type float
New in version 0.4.0.
rows
Returns a RangeRows object that represents the rows in the specified range.
New in version 0.9.0.
select()
Selects the range. Select only works on the active book.
New in version 0.9.0.
shape
Tuple of Range dimensions.
New in version 0.3.0.
sheet
Returns the Sheet object to which the Range belongs.
New in version 0.9.0.
size
Number of elements in the Range.
New in version 0.3.0.
table
Returns a Table object if the range is part of one, otherwise None.
New in version 0.21.0.
top
Returns the distance, in points, from the top edge of row 1 to the top edge of the range. Read-
only.
Returns
Return type float
New in version 0.6.0.
unmerge()
Separates a merged area into individual cells.
value
Gets and sets the values for the given Range.
Returns object
Return type returned object depends on the converter being used, see xlwings.
[Link]()
width
Returns the width, in points, of a Range. Read-only.
Returns
Return type float
New in version 0.4.0.
25.2.8 RangeRows
class [Link](rng)
Represents the rows of a range. Do not construct this class directly, use [Link] instead.
Example
import xlwings as xw
rng = [Link]('A1:C4')
[Link][0].value = 'a'
for r in [Link]:
print([Link])
autofit()
Autofits the height of the rows.
count
Returns the number of rows.
New in version 0.9.0.
25.2.9 RangeColumns
class [Link](rng)
Represents the columns of a range. Do not construct this class directly, use [Link] in-
stead.
Example
import xlwings as xw
rng = [Link]('A1:C4')
[Link][0].value = 'a'
for c in [Link]:
print([Link])
autofit()
Autofits the width of the columns.
count
Returns the number of columns.
New in version 0.9.0.
25.2.10 Shapes
class [Link](impl)
A collection of all shape objects on the specified sheet:
25.2.11 Shape
activate()
Activates the shape.
New in version 0.5.0.
api
Returns the native object (pywin32 or appscript obj) of the engine being used.
New in version 0.19.2.
delete()
Deletes the shape.
New in version 0.5.0.
height
Returns or sets the number of points that represent the height of the shape.
New in version 0.5.0.
left
Returns or sets the number of points that represent the horizontal position of the shape.
New in version 0.5.0.
name
Returns or sets the name of the shape.
New in version 0.5.0.
parent
Returns the parent of the shape.
New in version 0.9.0.
scale_height(factor, relative_to_original_size=False, scale=’scale_from_top_left’)
factor [float] For example 1.5 to scale it up to 150%
relative_to_original_size [bool, optional] If False, it scales relative to current height (de-
fault). For True must be a picture or OLE object.
scale [str, optional] One of scale_from_top_left (default),
scale_from_bottom_right, scale_from_middle
New in version 0.19.2.
scale_width(factor, relative_to_original_size=False, scale=’scale_from_top_left’)
factor [float] For example 1.5 to scale it up to 150%
relative_to_original_size [bool, optional] If False, it scales relative to current width (default).
For True must be a picture or OLE object.
scale [str, optional] One of scale_from_top_left (default),
scale_from_bottom_right, scale_from_middle
New in version 0.19.2.
text
Returns or sets the text of a shape.
New in version 0.21.4.
top
Returns or sets the number of points that represent the vertical position of the shape.
New in version 0.5.0.
type
Returns the type of the shape.
New in version 0.9.0.
width
Returns or sets the number of points that represent the width of the shape.
New in version 0.5.0.
25.2.12 Charts
class [Link](impl)
A collection of all chart objects on the specified sheet:
Examples
api
Returns the native object (pywin32 or appscript obj) of the engine being used.
count
Returns the number of objects in the collection.
25.2.13 Chart
api
Returns the native object (pywin32 or appscript obj) of the engine being used.
New in version 0.9.0.
chart_type
Returns and sets the chart type of the chart. The following chart types are available:
3d_area, 3d_area_stacked, 3d_area_stacked_100, 3d_bar_clustered,
3d_bar_stacked, 3d_bar_stacked_100, 3d_column, 3d_column_clustered,
3d_column_stacked, 3d_column_stacked_100, 3d_line, 3d_pie,
3d_pie_exploded, area, area_stacked, area_stacked_100, bar_clustered,
bar_of_pie, bar_stacked, bar_stacked_100, bubble, bubble_3d_effect,
column_clustered, column_stacked, column_stacked_100,
combination, cone_bar_clustered, cone_bar_stacked,
cone_bar_stacked_100, cone_col, cone_col_clustered,
cone_col_stacked, cone_col_stacked_100, cylinder_bar_clustered,
cylinder_bar_stacked, cylinder_bar_stacked_100,
cylinder_col, cylinder_col_clustered, cylinder_col_stacked,
cylinder_col_stacked_100, doughnut, doughnut_exploded, line,
line_markers, line_markers_stacked, line_markers_stacked_100,
line_stacked, line_stacked_100, pie, pie_exploded,
pie_of_pie, pyramid_bar_clustered, pyramid_bar_stacked,
pyramid_bar_stacked_100, pyramid_col, pyramid_col_clustered,
pyramid_col_stacked, pyramid_col_stacked_100, radar,
25.2.14 Pictures
class [Link](impl)
A collection of all picture objects on the specified sheet:
Examples
1. Picture
2. Matplotlib
api
Returns the native object (pywin32 or appscript obj) of the engine being used.
count
Returns the number of objects in the collection.
25.2.15 Picture
class [Link](impl=None)
The picture object is a member of the pictures collection:
25.2.16 Names
class [Link](impl)
A collection of all name objects in the workbook:
25.2.17 Name
class [Link](impl)
The name object is a member of the names collection:
delete()
Deletes the name.
New in version 0.9.0.
name
Returns or sets the name of the name object.
New in version 0.9.0.
refers_to
Returns or sets the formula that the name is defined to refer to, in A1-style notation, beginning
with an equal sign.
New in version 0.9.0.
refers_to_range
Returns the Range object referred to by a Name object.
New in version 0.9.0.
25.2.18 Tables
class [Link](impl)
A collection of all table objects on the specified sheet:
Examples
25.2.19 Table
parent
Returns the parent of the table.
range
Returns an xlwings range object of the table.
show_autofilter
Turn the autofilter on or off by setting it to True or False (read/write boolean)
show_headers
Show or hide the header (read/write)
show_table_style_column_stripes
Returns or sets if the Column Stripes table style is used for (read/write boolean)
show_table_style_first_column
Returns or sets if the first column is formatted (read/write boolean)
show_table_style_last_column
Returns or sets if the last column is displayed (read/write boolean)
show_table_style_row_stripes
Returns or sets if the Row Stripes table style is used (read/write boolean)
show_totals
Gets or sets a boolean to show/hide the Total row.
table_style
Gets or sets the table style. See [Link] for possible values.
totals_row_range
Returns an xlwings range object representing the Total row
update(data)
This method requires xlwings PRO
Updates the Excel table with the provided data. Currently restricted to DataFrames.
Changed in version 0.21.3.
Parameters data (pandas DataFrame) – Currently restricted to pandas
DataFrames. If you want to hide the index, set the first column as the index, e.g.
df.set_index('column_name').
Returns
Return type Table
Examples
import pandas as pd
import xlwings as xw
sheet = [Link]('[Link]').sheets[0]
(continues on next page)
# Sample DataFrame
nrows, ncols = 3, 3
df = [Link](data=nrows * [ncols * ['test']],
columns=['col ' + str(i) for i in range(ncols)])
# Hide the index, then insert a new table if it doesn't exist yet,
# otherwise update the existing one
df = df.set_index('col 0')
if table_name in [[Link] for table in [Link]]:
[Link][table_name].update(df)
else:
mytable = [Link](source=sheet['A1'], name=table_name).
˓→update(df)
import xlwings as xw
import numpy as np
(continues on next page)
@[Link]
@[Link]('x', [Link], ndim=2)
def add_one(x):
return x + 1
[Link](convert=None, **options)
Apply converters and options to return values, see also [Link]().
Examples
1) Suppress the index and header of a returned DataFrame:
import pandas as pd
@[Link]
@[Link](index=False, header=False)
def get_dataframe(n, m):
return [Link]([Link](n * m).reshape((n, m)))
2) Dynamic array:
Note: If your version of Excel supports the new native dynamic arrays, then you don’t have to
do anything special, and you shouldn’t use the expand decorator! To check if your version of
Excel supports it, see if you have the =UNIQUE() formula available. Native dynamic arrays were
introduced in Office 365 Insider Fast at the end of September 2018.
expand='table' turns the UDF into a dynamic array. Currently you must not use volatile func-
tions as arguments of a dynamic array, e.g. you cannot use =TODAY() as part of a dynamic array.
Also note that a dynamic array needs an empty row and column at the bottom and to the right and will
overwrite existing data without warning.
Unlike standard Excel arrays, dynamic arrays are being used from a single cell like a standard function
and auto-expand depending on the dimensions of the returned array:
import xlwings as xw
import numpy as np
@[Link]
@[Link](expand='table')
def dynamic_array(n, m):
return [Link](n * m).reshape((n, m))
25.4 Reports
Examples
In my_template.xlsx, put the following Jinja variables in two cells: {{ title }} and {{
df }}
With many template variables it may be useful to collect the data first:
**data)
You can control the Excel instance by passing in an xlwings App instance. For example, to run the
report in a separate and hidden instance of Excel, do the following:
REST API
26.1 Quickstart
xlwings offers an easy way to expose an Excel workbook via REST API both on Windows and macOS. This
can be useful when you have a workbook running on a single computer and want to access it from another
computer. Or you can build a Linux based web app that can interact with a legacy Excel application while
you are in the progress of migrating the Excel functionality into your web app (if you need help with that,
give us a shout).
You can run the REST API server from a command prompt or terminal as follows (this requires Flask>=1.0,
so make sure to pip install Flask):
Then perform a GET request e.g. via PowerShell on Windows or Terminal on Mac (while having an unsaved
“Book1” open). Note that you need to run the server and the GET request from two separate terminals (or
you can use something more convenient like Postman or Insomnia for testing the API):
$ curl "[Link]
{
"address": "$A$1:$B$2",
"color": null,
"column": 1,
"column_width": 10.0,
"count": 4,
"current_region": "$A$1:$B$2",
"formula": [
(continues on next page)
145
xlwings - Make Excel Fly!, Release dev
In the command prompt where your server is running, press Ctrl-C to shut it down again.
The xlwings REST API is a thin wrapper around the Python API which makes it very easy if you have
worked previously with xlwings. It also means that the REST API does require the Excel application to be
up and running which makes it a great choice if the data in your Excel workbook is constantly changing as
the REST API will always deliver the current state of the workbook without the need of saving it first.
Note: Currently, we only provide the GET methods to read the workbook. If you are also interested in
the POST methods to edit the workbook, let us know via GitHub issues. Some other things will also need
improvement, most notably exception handling.
xlwings restapi run will run a Flask development server on [Link] You can pro-
vide --host and --port as command line args and it also respects the Flask environment variables like
FLASK_ENV=development.
If you want to have more control, you can run the server directly with Flask, see the Flask docs for more
details:
set FLASK_APP=[Link]
flask run
26.3 Indexing
While the Python API offers Python’s 0-based indexing (e.g. [Link][0]) as well as Excel’s 1-based
indexing (e.g. [Link](1)), the REST API only offers 0-based indexing, e.g. /books/0.
The REST API accepts Range options as query parameters, see [Link]() e.g.
/book/book1/sheets/0/range/A1?expand=table&transpose=true
Remember that options only affect the value property.
26.6.1 /book
GET /book/<fullname_or_name>
Example response:
{
"app": 1104,
"fullname": "C:\\Users\\felix\\DEV\\xlwings\\scripts\\[Link]",
"name": "[Link]",
"names": [
"Sheet1!myname1",
"myname2"
],
"selection": "Sheet2!$A$1",
"sheets": [
"Sheet1",
"Sheet2"
]
}
GET /book/<fullname_or_name>/names
Example response:
{
"names": [
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
},
{
"name": "myname2",
"refers_to": "=Sheet1!$A$1"
}
]
}
GET /book/<fullname_or_name>/names/<name>
Example response:
{
"name": "myname2",
"refers_to": "=Sheet1!$A$1"
}
GET /book/<fullname_or_name>/names/<name>/range
Example response:
{
"address": "$A$1",
"color": null,
"column": 1,
"column_width": 8.47,
"count": 1,
"current_region": "$A$1:$B$2",
"formula": "=1+1.1",
"formula_array": "=1+1,1",
"height": 14.25,
"last_cell": "$A$1",
"left": 0.0,
"name": "myname2",
"number_format": "General",
"row": 1,
"row_height": 14.3,
"shape": [
1,
1
],
"size": 1,
"top": 0.0,
"value": 2.1,
"width": 51.0
}
GET /book/<fullname_or_name>/sheets
Example response:
{
"sheets": [
{
"charts": [
"Chart 1"
],
"name": "Sheet1",
"names": [
"Sheet1!myname1"
],
"pictures": [
"Picture 3"
],
"shapes": [
"Chart 1",
"Picture 3"
],
"used_range": "$A$1:$B$2"
},
{
"charts": [],
"name": "Sheet2",
"names": [],
(continues on next page)
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>
Example response:
{
"charts": [
"Chart 1"
],
"name": "Sheet1",
"names": [
"Sheet1!myname1"
],
"pictures": [
"Picture 3"
],
"shapes": [
"Chart 1",
"Picture 3"
],
"used_range": "$A$1:$B$2"
}
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/charts
Example response:
{
"charts": [
{
"chart_type": "line",
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"width": 355.0
}
]
}
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/charts/<chart_name_or_ix>
Example response:
{
"chart_type": "line",
(continues on next page)
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/names
Example response:
{
"names": [
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
}
]
}
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/names/<sheet_scope_name>
Example response:
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
}
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/names/<sheet_scope_name>/ran
Example response:
{
"address": "$B$2:$C$3",
"color": null,
"column": 2,
"column_width": 8.47,
"count": 4,
"current_region": "$A$1:$B$2",
"formula": [
[
"",
""
],
[
"",
""
]
],
"formula_array": "",
"height": 28.5,
(continues on next page)
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/pictures
Example response:
{
"pictures": [
{
"height": 100.0,
"left": 0.0,
"name": "Picture 3",
"top": 0.0,
"width": 100.0
}
]
}
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/pictures/<picture_name_or_ix
Example response:
{
"height": 100.0,
"left": 0.0,
"name": "Picture 3",
"top": 0.0,
"width": 100.0
}
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/range
Example response:
{
"address": "$A$1:$B$2",
"color": null,
"column": 1,
"column_width": 8.47,
"count": 4,
"current_region": "$A$1:$B$2",
"formula": [
[
"=1+1.1",
"a string"
],
[
"43395.0064583333",
""
]
],
"formula_array": null,
"height": 28.5,
"last_cell": "$B$2",
"left": 0.0,
"name": null,
"number_format": null,
"row": 1,
"row_height": 14.3,
"shape": [
2,
2
],
"size": 4,
"top": 0.0,
"value": [
[
2.1,
"a string"
],
[
"Mon, 22 Oct 2018 [Link] GMT",
null
]
],
"width": 102.0
}
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/range/<address>
Example response:
{
"address": "$A$1:$B$2",
(continues on next page)
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/shapes
Example response:
{
"shapes": [
{
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
(continues on next page)
GET /book/<fullname_or_name>/sheets/<sheet_name_or_ix>/shapes/<shape_name_or_ix>
Example response:
{
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"type": "chart",
"width": 355.0
}
26.6.2 /books
GET /books
Example response:
{
"books": [
{
"app": 1104,
"fullname": "Book1",
"name": "Book1",
"names": [],
"selection": "Sheet2!$A$1",
"sheets": [
"Sheet1"
]
},
{
"app": 1104,
"fullname": "C:\\Users\\felix\\DEV\\xlwings\\scripts\\[Link]",
"name": "[Link]",
(continues on next page)
GET /books/<book_name_or_ix>
Example response:
{
"app": 1104,
"fullname": "C:\\Users\\felix\\DEV\\xlwings\\scripts\\[Link]",
"name": "[Link]",
"names": [
"Sheet1!myname1",
"myname2"
],
"selection": "Sheet2!$A$1",
"sheets": [
"Sheet1",
"Sheet2"
]
}
GET /books/<book_name_or_ix>/names
Example response:
{
"names": [
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
},
(continues on next page)
GET /books/<book_name_or_ix>/names/<name>
Example response:
{
"name": "myname2",
"refers_to": "=Sheet1!$A$1"
}
GET /books/<book_name_or_ix>/names/<name>/range
Example response:
{
"address": "$A$1",
"color": null,
"column": 1,
"column_width": 8.47,
"count": 1,
"current_region": "$A$1:$B$2",
"formula": "=1+1.1",
"formula_array": "=1+1,1",
"height": 14.25,
"last_cell": "$A$1",
"left": 0.0,
"name": "myname2",
"number_format": "General",
"row": 1,
"row_height": 14.3,
"shape": [
1,
1
],
"size": 1,
"top": 0.0,
"value": 2.1,
"width": 51.0
}
GET /books/<book_name_or_ix>/sheets
Example response:
{
"sheets": [
(continues on next page)
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>
Example response:
{
"charts": [
"Chart 1"
],
"name": "Sheet1",
"names": [
"Sheet1!myname1"
],
"pictures": [
"Picture 3"
],
"shapes": [
"Chart 1",
"Picture 3"
],
"used_range": "$A$1:$B$2"
}
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/charts
Example response:
{
"charts": [
{
"chart_type": "line",
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"width": 355.0
}
]
}
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/charts/<chart_name_or_ix>
Example response:
{
"chart_type": "line",
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"width": 355.0
}
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/names
Example response:
{
"names": [
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
}
]
}
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/names/<sheet_scope_name>
Example response:
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
}
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/names/<sheet_scope_name>/ran
Example response:
{
"address": "$B$2:$C$3",
"color": null,
"column": 2,
"column_width": 8.47,
"count": 4,
"current_region": "$A$1:$B$2",
"formula": [
[
"",
""
],
[
"",
""
]
],
"formula_array": "",
"height": 28.5,
"last_cell": "$C$3",
"left": 51.0,
"name": "Sheet1!myname1",
"number_format": "General",
"row": 2,
"row_height": 14.3,
"shape": [
2,
2
],
"size": 4,
"top": 14.25,
"value": [
[
null,
null
],
[
null,
null
]
],
"width": 102.0
}
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/pictures
Example response:
{
"pictures": [
{
"height": 100.0,
"left": 0.0,
(continues on next page)
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/pictures/<picture_name_or_ix
Example response:
{
"height": 100.0,
"left": 0.0,
"name": "Picture 3",
"top": 0.0,
"width": 100.0
}
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/range
Example response:
{
"address": "$A$1:$B$2",
"color": null,
"column": 1,
"column_width": 8.47,
"count": 4,
"current_region": "$A$1:$B$2",
"formula": [
[
"=1+1.1",
"a string"
],
[
"43395.0064583333",
""
]
],
"formula_array": null,
"height": 28.5,
"last_cell": "$B$2",
"left": 0.0,
"name": null,
"number_format": null,
"row": 1,
"row_height": 14.3,
"shape": [
2,
2
],
(continues on next page)
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/range/<address>
Example response:
{
"address": "$A$1:$B$2",
"color": null,
"column": 1,
"column_width": 8.47,
"count": 4,
"current_region": "$A$1:$B$2",
"formula": [
[
"=1+1.1",
"a string"
],
[
"43395.0064583333",
""
]
],
"formula_array": null,
"height": 28.5,
"last_cell": "$B$2",
"left": 0.0,
"name": null,
"number_format": null,
"row": 1,
"row_height": 14.3,
"shape": [
2,
2
],
"size": 4,
"top": 0.0,
"value": [
[
(continues on next page)
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/shapes
Example response:
{
"shapes": [
{
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"type": "chart",
"width": 355.0
},
{
"height": 100.0,
"left": 0.0,
"name": "Picture 3",
"top": 0.0,
"type": "picture",
"width": 100.0
}
]
}
GET /books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/shapes/<shape_name_or_ix>
Example response:
{
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"type": "chart",
"width": 355.0
}
26.6.3 /apps
GET /apps
Example response:
{
"apps": [
{
"books": [
"Book1",
"C:\\Users\\felix\\DEV\\xlwings\\scripts\\[Link]",
"Book4"
],
"calculation": "automatic",
"display_alerts": true,
"pid": 1104,
"screen_updating": true,
"selection": "[[Link]]Sheet2!$A$1",
"version": "16.0",
"visible": true
},
{
"books": [
"Book2",
"Book5"
],
"calculation": "automatic",
"display_alerts": true,
"pid": 7920,
"screen_updating": true,
"selection": "[Book5]Sheet2!$A$1",
"version": "16.0",
"visible": true
}
]
}
GET /apps/<pid>
Example response:
{
"books": [
"Book1",
"C:\\Users\\felix\\DEV\\xlwings\\scripts\\[Link]",
"Book4"
],
"calculation": "automatic",
"display_alerts": true,
"pid": 1104,
"screen_updating": true,
"selection": "[[Link]]Sheet2!$A$1",
(continues on next page)
GET /apps/<pid>/books
Example response:
{
"books": [
{
"app": 1104,
"fullname": "Book1",
"name": "Book1",
"names": [],
"selection": "Sheet2!$A$1",
"sheets": [
"Sheet1"
]
},
{
"app": 1104,
"fullname": "C:\\Users\\felix\\DEV\\xlwings\\scripts\\[Link]",
"name": "[Link]",
"names": [
"Sheet1!myname1",
"myname2"
],
"selection": "Sheet2!$A$1",
"sheets": [
"Sheet1",
"Sheet2"
]
},
{
"app": 1104,
"fullname": "Book4",
"name": "Book4",
"names": [],
"selection": "Sheet2!$A$1",
"sheets": [
"Sheet1"
]
}
]
}
GET /apps/<pid>/books/<book_name_or_ix>
Example response:
{
(continues on next page)
GET /apps/<pid>/books/<book_name_or_ix>/names
Example response:
{
"names": [
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
},
{
"name": "myname2",
"refers_to": "=Sheet1!$A$1"
}
]
}
GET /apps/<pid>/books/<book_name_or_ix>/names/<name>
Example response:
{
"name": "myname2",
"refers_to": "=Sheet1!$A$1"
}
GET /apps/<pid>/books/<book_name_or_ix>/names/<name>/range
Example response:
{
"address": "$A$1",
"color": null,
"column": 1,
"column_width": 8.47,
"count": 1,
"current_region": "$A$1:$B$2",
"formula": "=1+1.1",
(continues on next page)
GET /apps/<pid>/books/<book_name_or_ix>/sheets
Example response:
{
"sheets": [
{
"charts": [
"Chart 1"
],
"name": "Sheet1",
"names": [
"Sheet1!myname1"
],
"pictures": [
"Picture 3"
],
"shapes": [
"Chart 1",
"Picture 3"
],
"used_range": "$A$1:$B$2"
},
{
"charts": [],
"name": "Sheet2",
"names": [],
"pictures": [],
"shapes": [],
"used_range": "$A$1"
}
]
}
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>
Example response:
{
"charts": [
"Chart 1"
],
"name": "Sheet1",
"names": [
"Sheet1!myname1"
],
"pictures": [
"Picture 3"
],
"shapes": [
"Chart 1",
"Picture 3"
],
"used_range": "$A$1:$B$2"
}
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/charts
Example response:
{
"charts": [
{
"chart_type": "line",
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"width": 355.0
}
]
}
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/charts/<chart_nam
Example response:
{
"chart_type": "line",
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"width": 355.0
}
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/names
Example response:
{
"names": [
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
}
]
}
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/names/<sheet_scop
Example response:
{
"name": "Sheet1!myname1",
"refers_to": "=Sheet1!$B$2:$C$3"
}
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/names/<sheet_scop
Example response:
{
"address": "$B$2:$C$3",
"color": null,
"column": 2,
"column_width": 8.47,
"count": 4,
"current_region": "$A$1:$B$2",
"formula": [
[
"",
""
],
[
"",
""
]
],
"formula_array": "",
"height": 28.5,
"last_cell": "$C$3",
"left": 51.0,
"name": "Sheet1!myname1",
"number_format": "General",
"row": 2,
"row_height": 14.3,
"shape": [
2,
2
],
"size": 4,
"top": 14.25,
(continues on next page)
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/pictures
Example response:
{
"pictures": [
{
"height": 100.0,
"left": 0.0,
"name": "Picture 3",
"top": 0.0,
"width": 100.0
}
]
}
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/pictures/<picture
Example response:
{
"height": 100.0,
"left": 0.0,
"name": "Picture 3",
"top": 0.0,
"width": 100.0
}
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/range
Example response:
{
"address": "$A$1:$B$2",
"color": null,
"column": 1,
"column_width": 8.47,
"count": 4,
"current_region": "$A$1:$B$2",
(continues on next page)
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/range/<address>
Example response:
{
"address": "$A$1:$B$2",
"color": null,
"column": 1,
"column_width": 8.47,
"count": 4,
"current_region": "$A$1:$B$2",
"formula": [
[
"=1+1.1",
"a string"
(continues on next page)
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/shapes
Example response:
{
"shapes": [
{
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"type": "chart",
"width": 355.0
},
{
"height": 100.0,
"left": 0.0,
"name": "Picture 3",
"top": 0.0,
(continues on next page)
GET /apps/<pid>/books/<book_name_or_ix>/sheets/<sheet_name_or_ix>/shapes/<shape_nam
Example response:
{
"height": 211.0,
"left": 0.0,
"name": "Chart 1",
"top": 0.0,
"type": "chart",
"width": 355.0
}
175
xlwings - Make Excel Fly!, Release dev
176 Index
xlwings - Make Excel Fly!, Release dev
Index 177
xlwings - Make Excel Fly!, Release dev
X
xlwings (module), 105
[Link]() (in module xlwings), 140
[Link]() (in module xlwings), 140
[Link] (module), 142
[Link]() (in module xlwings), 141
[Link]() (in module xlwings), 140
178 Index