Blog
How To Create Horizontal Gradient Filled Clustered Column Chart Using xlwings?
【Example】

【Code】
import xlwings as xw
import os
def set_style(cht):
cht.ChartArea.Format.Line.Visible=False
cht.PlotArea.Format.Fill.Visible = False
cht.PlotArea.Format.Line.Visible = True
cht.PlotArea.Format.Line.ForeColor.RGB=xw.utils.rgb_to_int((200,200,200))
#cht.PlotArea.Format.Line.ForeColor.ObjectThemeColor = msoThemeColorText1
ax1 = cht.Axes(1)
ax2 = cht.Axes(2)
ax1.HasTitle = True
ax1.AxisTitle.Text = 'Categories'
ax1.AxisTitle.Font.Size = 10
ax1.TickLabels.Font.Size = 8
#ax1.TickLabels.NumberFormat = '0.00'
ax1.HasMajorGridlines = True
ax2.HasTitle = True
ax2.AxisTitle.Text = 'Values'
ax2.AxisTitle.Font.Size = 10
ax2.TickLabels.Font.Size = 8
ax2.HasMajorGridlines = True
cht.HasTitle = True
#cht.ChartTitle.Caption = 'Plot'
#cht.ChartTitle.Font.Size = 12
root=os.getcwd()
app=xw.App(visible=True,add_book=False)
wb=app.books.open(root+r'/data.xlsx',read_only=False)
sht=wb.sheets('Sheet1')
sht.api.Range('A2:C10').Select() #
shp=sht.api.Shapes.AddChart2(-1,xw.constants.ChartType.xlColumnClustered,20,20,400,250,True)
cht=shp.Chart #
cht.ChartGroups(1).GapWidth=50
cht.SeriesCollection(1).Format.Fill.ForeColor.RGB=xw.utils.rgb_to_int((0,0,255))
cht.SeriesCollection(1).Format.Fill.OneColorGradient(2,1,1) #msoGradientVertical
cht.SeriesCollection(1).Format.Fill.GradientStops.Insert(xw.utils.rgb_to_int((255,255,255)),0.5)
cht.SeriesCollection(1).Format.Fill.GradientStops.Delete(2)
cht.SeriesCollection(1).Format.Fill.GradientStops.Insert(xw.utils.rgb_to_int((0,0,255)),1)
cht.SeriesCollection(2).Format.Fill.ForeColor.RGB=xw.utils.rgb_to_int((255,128,0))
cht.SeriesCollection(2).Format.Fill.OneColorGradient(2,1,1) #msoGradientVertical
cht.SeriesCollection(2).Format.Fill.GradientStops.Insert(xw.utils.rgb_to_int((255,255,255)),0.5)
cht.SeriesCollection(2).Format.Fill.GradientStops.Delete(2)
cht.SeriesCollection(2).Format.Fill.GradientStops.Insert(xw.utils.rgb_to_int((255,128,0)),1)
cht.HasLegend=True
set_style(cht)
cht.Export(root+'/cht.jpg')
cht.Export(root+'/cht.svg')
cht.ExportAsFixedFormat(0,root+'/cht.pdf')
#wb.save()
#app.kill()

How to use Application.Run in the xlwings API way
The Application.Run method in Excel’s object model is a powerful tool for executing procedures, such as macros or user-defined functions, that are stored in Excel workbooks. In xlwings, this functionality is exposed through the api property, which provides direct access to the underlying Excel object model. This allows Python scripts to interact with Excel in a manner similar to VBA, enabling the automation of complex tasks and the integration of custom VBA code with Python workflows.
Functionality:
The primary purpose of Application.Run is to run a specified macro or function. This can include macros defined in VBA modules, functions in add-ins, or procedures in other open workbooks. It is particularly useful for scenarios where you need to trigger existing VBA code from an external Python script, leveraging the strengths of both environments. For instance, you might use Python for data processing and analysis, then call a VBA macro to format the results or generate a specific report layout that is already built in Excel.
Syntax in xlwings:
In xlwings, you access this method via the Application object obtained from a workbook or app instance. The basic syntax is:
app.api.Run(Macro, Arg1, Arg2, ..., Arg30)
Where:
app: This is the xlwings App object (e.g.,xw.App()orxw.apps.active).Macro: A required string argument specifying the name of the macro or function to run. The name should be in the format"WorkbookName!MacroName"or"MacroName"if the macro is in the current workbook. For add-ins, you might use the add-in’s registered name.Arg1, Arg2, ..., Arg30: Optional arguments that can be passed to the macro. You can provide up to 30 arguments, which correspond to the parameters expected by the VBA procedure. These arguments can be of various data types, such as strings, numbers, or arrays, and they are passed by value to the macro.
Example Usage:
Suppose you have an Excel workbook named Report.xlsm with a VBA macro named FormatData that takes two arguments: a range address as a string and a boolean for enabling headers. You can call this macro from Python using xlwings as follows:
import xlwings as xw
# Connect to the open instance of Excel or start a new one
app = xw.apps.active # Assumes Excel is already open with the workbook
# Specify the macro name with workbook reference
macro_name = "Report.xlsm!FormatData"
# Define arguments: range address and header flag
range_address = "A1:D100"
headers_enabled = True
# Run the macro with arguments
app.api.Run(macro_name, range_address, headers_enabled)
# Alternatively, if the macro is in the active workbook, you can use:
# app.api.Run("FormatData", range_address, headers_enabled)
How To Create Overlayed Column Chart Using xlwings?
【Example】

【Code】
import xlwings as xw
import os
def set_style(cht):
cht.ChartArea.Format.Line.Visible=False
cht.PlotArea.Format.Fill.Visible = False
cht.PlotArea.Format.Line.Visible = True
cht.PlotArea.Format.Line.ForeColor.RGB=xw.utils.rgb_to_int((200,200,200))
#cht.PlotArea.Format.Line.ForeColor.ObjectThemeColor = msoThemeColorText1
ax1 = cht.Axes(1)
ax2 = cht.Axes(2)
ax1.HasTitle = True
ax1.AxisTitle.Text = 'Categories'
ax1.AxisTitle.Font.Size = 10
ax1.TickLabels.Font.Size = 8
#ax1.TickLabels.NumberFormat = '0.00'
ax1.HasMajorGridlines = True
ax2.HasTitle = True
ax2.AxisTitle.Text = 'Values'
ax2.AxisTitle.Font.Size = 10
ax2.TickLabels.Font.Size = 8
ax2.HasMajorGridlines = True
cht.HasTitle = True
#cht.ChartTitle.Caption = 'Plot'
#cht.ChartTitle.Font.Size = 12
root=os.getcwd()
app=xw.App(visible=True,add_book=False)
wb=app.books.open(root+r'/data.xlsx',read_only=False)
sht=wb.sheets('Sheet1')
sht.api.Range('A2:C10').Select() #
shp=sht.api.Shapes.AddChart2(-1,xw.constants.ChartType.xlColumnClustered,20,20,350,250,True)
cht=shp.Chart #
cht.ChartGroups(1).GapWidth=50
cht.ChartGroups(1).Overlap=50
clr2=cht.SeriesCollection(2).Format.Fill.ForeColor
cht.SeriesCollection(2).Format.Fill.ForeColor=clr2
cht.SeriesCollection(2).Format.Fill.Transparency=0.3
set_style(cht)
cht.HasLegend=True
cht.Export(root+'/cht.jpg')
cht.Export(root+'/cht.svg')
cht.ExportAsFixedFormat(0,root+'/cht.pdf')
#wb.save()
#app.kill()

How to use Application.Repeat in the xlwings API way
The Application.Repeat property in Excel, when accessed via the xlwings API, is a read-only property that returns a Boolean value indicating whether the last user-interface action (such as a command or operation) can be repeated. This property is part of the Excel Application object model and is useful for building macros or applications that need to check the repeatability of an action before attempting to execute it again, often in conjunction with the Repeat method.
Functionality
The Application.Repeat property checks if the last action performed by the user in Excel can be repeated. This is typically used in custom VBA macros or add-ins to provide feedback or enable/disable repeat functionality in a user interface. In xlwings, it allows Python scripts to interact with Excel’s state, enabling automation that responds to user actions or workflow conditions. For instance, you might use it to verify that a formatting change or data entry can be repeated before proceeding with a batch operation.
Syntax
In xlwings, the Repeat property is accessed through the app object, which represents the Excel Application. The syntax is straightforward since it is a property with no parameters:
app.api.Repeat
Here, app is an instance of the xlwings App class (e.g., created with xw.App() or xw.apps). The .api attribute provides direct access to the underlying Excel object model, allowing you to call properties like Repeat. The property returns a Boolean:
True: The last action can be repeated.False: The last action cannot be repeated, or no action is available to repeat.
Example
Below is a code example demonstrating how to use the Application.Repeat property in xlwings. This script checks if the last user action in Excel is repeatable and prints a message accordingly. It also shows a practical scenario where you might conditionally execute a repeat operation.
import xlwings as xw
# Connect to the active Excel instance or start a new one
app = xw.apps.active # Use the currently running Excel application
# Check if the last action can be repeated
repeat_status = app.api.Repeat
if repeat_status:
print("The last action in Excel can be repeated.")
# Optionally, you could use app.api.Repeat() to perform the repeat action
# Note: app.api.Repeat() is a method that repeats the last action
try:
app.api.Repeat() # This repeats the last user-interface action
print("Action repeated successfully.")
except Exception as e:
print(f"Error repeating action: {e}")
else:
print("The last action in Excel cannot be repeated or no action is available.")
# Example with a specific action: Let's assume a user just formatted a cell
# We'll simulate checking after a potential action
# First, ensure we have a workbook and range
wb = app.books.active
sheet = wb.sheets.active
cell = sheet.range("A1")
cell.value = "Test"
cell.api.Font.Bold = True # Apply bold formatting as an action
# Now check the Repeat property after this formatting
repeat_status_after = app.api.Repeat
print(f"After formatting A1 as bold, Repeat status: {repeat_status_after}")
# In many cases, formatting actions are repeatable, so this might return True
# You can use this to automate repetitive tasks based on user actions
Notes
- The
Repeatproperty is often used in tandem with theRepeatmethod (app.api.Repeat()), which actually repeats the last action. However, the property only indicates feasibility without performing the action. - In xlwings, accessing
app.api.Repeatdirectly mirrors the VBAApplication.Repeatproperty, ensuring compatibility with Excel’s behavior. - The property may return
Falseif no previous action exists or if the action is not repeatable (e.g., some dialog-based operations). Always handle potential errors when using the related method. - This property is primarily relevant for user-interface interactions; in automated scripts, its value depends on the last action performed, which could be from the script itself or manual user input.
How To Create 100% Stacked Column Chart Using xlwings?
【Example】

【Code】
import xlwings as xw
import os
def set_style(cht):
cht.ChartArea.Format.Line.Visible=False
cht.PlotArea.Format.Fill.Visible = False
cht.PlotArea.Format.Line.Visible = True
cht.PlotArea.Format.Line.ForeColor.RGB=xw.utils.rgb_to_int((200,200,200))
#cht.PlotArea.Format.Line.ForeColor.ObjectThemeColor = msoThemeColorText1
ax1 = cht.Axes(1)
ax2 = cht.Axes(2)
ax1.HasTitle = True
ax1.AxisTitle.Text = 'Categories'
ax1.AxisTitle.Font.Size = 10
ax1.TickLabels.Font.Size = 8
#ax1.TickLabels.NumberFormat = '0.00'
ax1.HasMajorGridlines = True
ax2.HasTitle = True
ax2.AxisTitle.Text = 'Values'
ax2.AxisTitle.Font.Size = 10
ax2.TickLabels.Font.Size = 8
ax2.HasMajorGridlines = True
cht.HasTitle = True
#cht.ChartTitle.Caption = 'Plot'
#cht.ChartTitle.Font.Size = 12
root=os.getcwd()
app=xw.App(visible=True,add_book=False)
wb=app.books.open(root+r'/data.xlsx',read_only=False)
sht=wb.sheets('Sheet1')
sht.api.Range('A2:C11').Select() #
shp=sht.api.Shapes.AddChart2(-1,xw.constants.ChartType.xlColumnStacked100,20,20,350,250,True)
cht=shp.Chart #
cht.ChartGroups(1).GapWidth=50
set_style(cht)
cht.Export(root+'/cht.jpg')
cht.Export(root+'/cht.svg')
cht.ExportAsFixedFormat(0,root+'/cht.pdf')
#wb.save()
#app.kill()

How to use Application.RegisterXLL in the xlwings API way
The RegisterXLL member of the Application object in Excel is a method that loads and registers an Excel add-in (XLL) file. XLLs are dynamic-link libraries (DLLs) specifically designed for Excel, providing custom functions, commands, or features that extend Excel’s native capabilities. In xlwings, this method allows you to programmatically register an XLL add-in from your Python code, enabling the use of its functions within Excel. This is particularly useful for automating workflows that depend on custom add-ins or for ensuring that required add-ins are loaded before executing certain tasks.
Syntax in xlwings:
app.api.RegisterXLL(Filename)
Here, app is an instance of the xlwings App class, representing the Excel application. The .api property provides access to the underlying Excel object model. The RegisterXLL method takes one parameter:
Filename(string, required): The full path and file name of the XLL add-in to be registered. For example,r"C:\AddIns\MyFunctions.xll".
If the registration is successful, the method returns True; if it fails (e.g., due to an invalid file path or compatibility issues), it returns False.
Example:
Suppose you have an XLL add-in named FinancialTools.xll located in a network drive. The following xlwings code registers this add-in in Excel and then uses a custom function from it to calculate a value. This example assumes Excel is already running or will be started by xlwings.
import xlwings as xw
import os
# Start or connect to Excel
app = xw.App(visible=True)
# Define the path to the XLL file
xll_path = r"\\server\share\AddIns\FinancialTools.xll"
# Check if the file exists before attempting to register
if os.path.exists(xll_path):
# Register the XLL add-in
success = app.api.RegisterXLL(xll_path)
if success:
print("Add-in registered successfully.")
# Open a workbook (or use the active one)
wb = app.books.open(r"C:\Data\Report.xlsx")
# Use a custom function from the add-in, e.g., a user-defined function (UDF) named "CalculateNPV"
# This writes the formula into cell A1 of the first sheet
wb.sheets[0].range("A1").formula = "=CalculateNPV(B1:B10, 0.1)"
# Calculate to ensure the formula is evaluated
wb.api.Calculate()
# Read the result
result = wb.sheets[0].range("A1").value
print(f"Calculated NPV: {result}")
else:
print("Failed to register the add-in.")
else:
print("XLL file not found.")
# Close the workbook and quit Excel (optional)
wb.close()
app.quit()
How To Create Stacked Column Chart Using xlwings?
【Example】

【Code】
import xlwings as xw
import os
def set_style(cht):
cht.ChartArea.Format.Line.Visible=False
cht.PlotArea.Format.Fill.Visible = False
cht.PlotArea.Format.Line.Visible = True
cht.PlotArea.Format.Line.ForeColor.RGB=xw.utils.rgb_to_int((200,200,200))
#cht.PlotArea.Format.Line.ForeColor.ObjectThemeColor = msoThemeColorText1
ax1 = cht.Axes(1)
ax2 = cht.Axes(2)
ax1.HasTitle = True
ax1.AxisTitle.Text = 'Categories'
ax1.AxisTitle.Font.Size = 10
ax1.TickLabels.Font.Size = 8
#ax1.TickLabels.NumberFormat = '0.00'
ax1.HasMajorGridlines = True
ax2.HasTitle = True
ax2.AxisTitle.Text = 'Values'
ax2.AxisTitle.Font.Size = 10
ax2.TickLabels.Font.Size = 8
ax2.HasMajorGridlines = True
cht.HasTitle = True
#cht.ChartTitle.Caption = 'Plot'
#cht.ChartTitle.Font.Size = 12
root=os.getcwd()
app=xw.App(visible=True,add_book=False)
wb=app.books.open(root+r'/data.xlsx',read_only=False)
sht=wb.sheets('Sheet1')
sht.api.Range('A2:C11').Select() #
shp=sht.api.Shapes.AddChart2(-1,xw.constants.ChartType.xlColumnStacked,20,20,350,250,True)
cht=shp.Chart #
cht.ChartGroups(1).GapWidth=50
set_style(cht)
cht.Export(root+'/cht.jpg')
cht.Export(root+'/cht.svg')
cht.ExportAsFixedFormat(0,root+'/cht.pdf')
#wb.save()
#app.kill()

How to use Application.RecordMacro in the xlwings API way
The Application.RecordMacro method in Excel’s object model is a powerful feature for automating the recording of a sequence of actions into a VBA macro. In xlwings, this functionality is exposed through the api property, which provides direct access to the underlying COM object, allowing you to leverage Excel’s native methods. This is particularly useful for developers who need to programmatically initiate macro recording, such as in testing scenarios or when building tools that assist users in creating macros without manually clicking the record button.
Functionality:
The primary purpose of RecordMacro is to start the macro recorder in Excel. When invoked, it begins capturing user interactions (like cell edits, formatting changes, or menu selections) and translates them into VBA code. This recorded code can then be saved to a module for later execution. In an automation context, using RecordMacro via xlwings enables scripts to trigger this recording process seamlessly, integrating macro generation into larger Python-based workflows.
Syntax in xlwings:
The method is called through the Application object. In xlwings, you typically access this via the app object representing an Excel instance. The syntax is:
app.api.RecordMacro(BasicCode, XlmCode)
- BasicCode (Optional, Variant): A string that specifies the VBA code to be used as the macro. If provided, Excel will use this code directly instead of recording actions. If omitted, Excel starts recording interactively.
- XlmCode (Optional, Variant): A string that specifies Excel 4.0 macro language (XLM) code. This is rarely used in modern contexts and is primarily for backward compatibility. It can be omitted.
Both parameters are optional. If neither is supplied, Excel begins recording a macro normally, prompting the user to save it later. If BasicCode is provided, Excel writes that code to a new module without interactive recording.
Code Examples:
Below are practical examples demonstrating how to use RecordMacro with xlwings.
- Starting Interactive Macro Recording:
This example opens Excel and initiates the macro recorder, which will capture subsequent manual actions.
import xlwings as xw
# Connect to a running Excel instance or start a new one
app = xw.apps.active or xw.App()
# Start recording a macro interactively
app.api.RecordMacro()
# At this point, perform actions in Excel (e.g., type in a cell)
# After completing actions, stop recording via Excel's UI or programmatically
# Note: Stopping recording programmatically isn't direct via RecordMacro; it requires sending keystrokes or using SendKeys.
- Providing Predefined VBA Code:
Instead of interactive recording, you can supply VBA code directly. This example creates a macro that inserts a timestamp.
import xlwings as xw
app = xw.apps.active or xw.App()
vba_code = """
Sub InsertTimestamp()
ActiveCell.Value = Now()
End Sub
"""
# Record the macro using the provided code
app.api.RecordMacro(BasicCode=vba_code)
# This will create a macro named "InsertTimestamp" in a new module
# Save the workbook to retain the macro
app.books.active.save()
- Integrating with User Workflows:
In a tool that guides users, you might combineRecordMacrowith other xlwings features. For instance, after preparing a worksheet, you could start recording for custom user actions.
import xlwings as xw
app = xw.App(visible=True)
wb = app.books.add()
ws = wb.sheets[0]
ws.range("A1").value = "Start recording your macro below:"
# Prompt user and begin recording
input("Press Enter to start macro recording...")
app.api.RecordMacro()
print("Recording started. Perform actions in Excel, then stop recording manually.")
Important Notes:
- When using
RecordMacrowithout parameters, the recording must be stopped manually by the user (e.g., clicking the stop button in Excel). Automating the stop process is complex and may require simulating keystrokes viaSendKeysor using Windows API calls, which is beyond xlwings’ core functionality. - The method is part of Excel’s COM interface; thus, it requires Excel to be running and may have limitations in headless environments. Ensure Excel is visible (
visible=True) for interactive recording. - For advanced automation, consider generating VBA code directly via xlwings’
vbamodule or using Python to write to modules, as this offers more control than relying on recording.
How To Create Clustered Column Chart Using xlwings?
【Example】

【Code】
import xlwings as xw
import os
def set_style(cht):
cht.ChartArea.Format.Line.Visible=False
cht.PlotArea.Format.Fill.Visible = False
cht.PlotArea.Format.Line.Visible = True
cht.PlotArea.Format.Line.ForeColor.RGB=xw.utils.rgb_to_int((200,200,200))
#cht.PlotArea.Format.Line.ForeColor.ObjectThemeColor = msoThemeColorText1
ax1 = cht.Axes(1)
ax2 = cht.Axes(2)
ax1.HasTitle = True
ax1.AxisTitle.Text = 'Categories'
ax1.AxisTitle.Font.Size = 10
ax1.TickLabels.Font.Size = 8
#ax1.TickLabels.NumberFormat = '0.00'
ax1.HasMajorGridlines = True
ax2.HasTitle = True
ax2.AxisTitle.Text = 'Values'
ax2.AxisTitle.Font.Size = 10
ax2.TickLabels.Font.Size = 8
ax2.HasMajorGridlines = True
cht.HasTitle = True
#cht.ChartTitle.Caption = 'Plot'
#cht.ChartTitle.Font.Size = 12
root=os.getcwd()
app=xw.App(visible=True,add_book=False)
wb=app.books.open(root+r'/data.xlsx',read_only=False)
sht=wb.sheets('Sheet1')
sht.api.Range('A2:C7').Select() #
shp=sht.api.Shapes.AddChart2(-1,xw.constants.ChartType.xlColumnClustered,20,20,350,250,True)
cht=shp.Chart #
set_style(cht)
cht.Export(root+'/cht.jpg')
cht.Export(root+'/cht.svg')
cht.ExportAsFixedFormat(0,root+'/cht.pdf')
#wb.save()
#app.kill()

How to use Application.Quit in the xlwings API way
The Application.Quit method in Excel’s object model is a critical command for programmatically closing the Excel application itself. When automating tasks using xlwings, a Python library that interacts with Excel via its COM API, the Quit method provides a clean and controlled way to terminate the Excel process, especially after a script has completed its operations. This is essential for resource management, ensuring that no hidden Excel instances remain running in the background, which could consume memory and system resources. In xlwings, this method is accessed through the App object, which represents the Excel application.
Functionality:
The primary function of Quit is to close the Microsoft Excel application. It is analogous to manually clicking the close button (the “X”) on the Excel window or selecting “Exit” from the File menu. When invoked, it prompts Excel to close all open workbooks. If there are any unsaved changes in any open workbook, Excel will typically display a dialog box asking the user to save, discard changes, or cancel the quit operation, unless this default behavior is overridden by other settings (like DisplayAlerts being set to False).
Syntax in xlwings:
The xlwings API provides a Pythonic way to call this method. The general syntax is:
app.quit()
Here, app is an instance of the xlwings.App class, representing a running Excel application. The quit() method does not take any parameters in its xlwings implementation. It’s a direct wrapper around the underlying COM Quit method.
Important Considerations and Parameters:
While the xlwings app.quit() method itself has no arguments, the behavior upon quitting is influenced by the state of Excel’s DisplayAlerts property and the Saved status of workbooks. To quit without being prompted to save, you can set DisplayAlerts to False before calling quit(). However, this will discard any unsaved changes without warning.
| Related Setting | xlwings Access | Effect on Quit |
|---|---|---|
DisplayAlerts | app.display_alerts = False | Suppresses save prompts; unsaved data is lost. |
Workbook Saved Property | wb.saved = True | Marks a workbook as saved, preventing a prompt for that specific book. |
Code Examples:
- Basic Quit: This example starts Excel, creates a new workbook, and then closes the application. If the workbook has not been saved, a prompt will appear.
import xlwings as xw
# Start Excel and create a new workbook
app = xw.App(visible=True)
wb = app.books.add()
# ... perform some operations ...
# Quit Excel (may show save prompt)
app.quit()
- Quit Without Save Prompts: This example demonstrates how to force Excel to close immediately, discarding any unsaved changes by turning off alerts.
import xlwings as xw
app = xw.App(visible=True)
wb = app.books.add()
wb.sheets[0].range('A1').value = "Unsaved Data"
# Disable alert dialogs
app.display_alerts = False
# Quit Excel; no prompt will appear, and changes are lost
app.quit()
- Quit After Saving: A more controlled approach is to save workbooks explicitly before quitting.
import xlwings as xw
import os
app = xw.App(visible=True)
wb = app.books.add()
wb.sheets[0].range('A1').value = "Important Data"
# Save the workbook to a specific path
file_path = os.path.join(os.getcwd(), 'report.xlsx')
wb.save(file_path)
# Now it's safe to quit without prompts
app.quit()