excel-automation
Advanced Excel automation with Python using xlwings - interact with live Excel instances
What this skill does
# Excel Automation Skill
## Overview
This skill enables advanced Excel automation using **xlwings** - a library that can interact with live Excel instances. Unlike openpyxl (file-only), xlwings can control Excel in real-time, execute VBA, update dashboards, and automate complex workflows.
## How to Use
1. Describe the Excel automation task you need
2. Specify if you need live Excel interaction or file processing
3. I'll generate xlwings code and execute it
**Example prompts:**
- "Update this live Excel dashboard with new data"
- "Run this VBA macro and get the results"
- "Create an Excel add-in for data validation"
- "Automate monthly report generation with live charts"
## Domain Knowledge
### xlwings vs openpyxl
| Feature | xlwings | openpyxl |
|---------|---------|----------|
| Requires Excel | Yes | No |
| Live interaction | Yes | No |
| VBA execution | Yes | No |
| Speed (large files) | Fast | Slow |
| Server deployment | Limited | Easy |
### xlwings Fundamentals
```python
import xlwings as xw
# Connect to active Excel workbook
wb = xw.Book.caller() # From Excel add-in
wb = xw.books.active # Active workbook
# Open specific file
wb = xw.Book('path/to/file.xlsx')
# Create new workbook
wb = xw.Book()
# Get sheet
sheet = wb.sheets['Sheet1']
sheet = wb.sheets[0]
```
### Working with Ranges
#### Reading and Writing
```python
# Single cell
sheet['A1'].value = 'Hello'
value = sheet['A1'].value
# Range
sheet['A1:C3'].value = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
data = sheet['A1:C3'].value # Returns list of lists
# Named range
sheet['MyRange'].value = 'Named data'
# Expand range (detect data boundaries)
sheet['A1'].expand().value # All connected data
sheet['A1'].expand('table').value # Table format
```
#### Dynamic Ranges
```python
# Current region (like Ctrl+Shift+End)
data = sheet['A1'].current_region.value
# Used range
used = sheet.used_range.value
# Last row with data
last_row = sheet['A1'].end('down').row
# Resize range
rng = sheet['A1'].resize(10, 5) # 10 rows, 5 columns
```
### Formatting
```python
# Font
sheet['A1'].font.bold = True
sheet['A1'].font.size = 14
sheet['A1'].font.color = (255, 0, 0) # RGB red
# Fill
sheet['A1'].color = (255, 255, 0) # Yellow background
# Number format
sheet['B1'].number_format = '$#,##0.00'
# Column width
sheet['A:A'].column_width = 20
# Row height
sheet['1:1'].row_height = 30
# Autofit
sheet['A:D'].autofit()
```
### Excel Features
#### Charts
```python
# Add chart
chart = sheet.charts.add(left=100, top=100, width=400, height=250)
chart.set_source_data(sheet['A1:B10'])
chart.chart_type = 'column_clustered'
chart.name = 'Sales Chart'
# Modify existing chart
chart = sheet.charts['Sales Chart']
chart.chart_type = 'line'
```
#### Tables
```python
# Create Excel Table
rng = sheet['A1'].expand()
table = sheet.tables.add(source=rng, name='SalesTable')
# Refresh table
table.refresh()
# Access table data
table_data = table.data_body_range.value
```
#### Pictures
```python
# Add picture
sheet.pictures.add('logo.png', left=10, top=10, width=100, height=50)
# Update picture from matplotlib
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
sheet.pictures.add(fig, name='MyPlot', update=True)
```
### VBA Integration
```python
# Run VBA macro
wb.macro('MacroName')()
# With arguments
wb.macro('MyMacro')('arg1', 'arg2')
# Get return value
result = wb.macro('CalculateTotal')(100, 200)
# Access VBA module
vb_code = wb.api.VBProject.VBComponents('Module1').CodeModule.Lines(1, 10)
```
### User Defined Functions (UDFs)
```python
# Define a UDF (in Python file)
import xlwings as xw
@xw.func
def my_sum(x, y):
"""Add two numbers"""
return x + y
@xw.func
@xw.arg('data', ndim=2)
def my_array_func(data):
"""Process array data"""
import numpy as np
return np.sum(data)
# These become Excel functions: =my_sum(A1, B1)
```
### Application Control
```python
# Excel application settings
app = xw.apps.active
app.screen_updating = False # Speed up
app.calculation = 'manual' # Manual calc
app.display_alerts = False # Suppress dialogs
# Perform operations...
# Restore
app.screen_updating = True
app.calculation = 'automatic'
app.display_alerts = True
```
## Best Practices
1. **Disable Screen Updating**: For batch operations
2. **Use Arrays**: Read/write entire ranges, not cell-by-cell
3. **Manual Calculation**: Turn off auto-calc during data loading
4. **Close Connections**: Properly close workbooks when done
5. **Error Handling**: Handle Excel not being installed
## Common Patterns
### Performance Optimization
```python
import xlwings as xw
def batch_update(data, workbook_path):
app = xw.App(visible=False)
try:
app.screen_updating = False
app.calculation = 'manual'
wb = app.books.open(workbook_path)
sheet = wb.sheets['Data']
# Write all data at once
sheet['A1'].value = data
app.calculation = 'automatic'
wb.save()
finally:
wb.close()
app.quit()
```
### Dashboard Update
```python
def update_dashboard(data_dict):
wb = xw.books.active
# Update data sheet
data_sheet = wb.sheets['Data']
for name, values in data_dict.items():
data_sheet[name].value = values
# Refresh all charts
dashboard = wb.sheets['Dashboard']
for chart in dashboard.charts:
chart.refresh()
# Update timestamp
from datetime import datetime
dashboard['A1'].value = f'Last Updated: {datetime.now()}'
```
### Report Generator
```python
def generate_monthly_report(month, data):
template = xw.Book('template.xlsx')
# Fill data
sheet = template.sheets['Report']
sheet['B2'].value = month
sheet['A5'].value = data
# Run calculations
template.app.calculate()
# Export to PDF
sheet.api.ExportAsFixedFormat(0, f'report_{month}.pdf')
template.save(f'report_{month}.xlsx')
```
## Examples
### Example 1: Live Dashboard Update
```python
import xlwings as xw
import pandas as pd
from datetime import datetime
# Connect to running Excel
wb = xw.books.active
dashboard = wb.sheets['Dashboard']
data_sheet = wb.sheets['Data']
# Fetch new data (simulated)
new_data = pd.DataFrame({
'Date': pd.date_range('2024-01-01', periods=30),
'Sales': [1000 + i*50 for i in range(30)],
'Costs': [600 + i*30 for i in range(30)]
})
# Update data sheet
data_sheet['A1'].value = new_data
# Calculate profit
data_sheet['D1'].value = 'Profit'
data_sheet['D2'].value = '=B2-C2'
data_sheet['D2'].expand('down').value = data_sheet['D2'].formula
# Update KPIs on dashboard
dashboard['B2'].value = new_data['Sales'].sum()
dashboard['B3'].value = new_data['Costs'].sum()
dashboard['B4'].value = new_data['Sales'].sum() - new_data['Costs'].sum()
dashboard['A1'].value = f'Updated: {datetime.now().strftime("%Y-%m-%d %H:%M")}'
# Refresh charts
for chart in dashboard.charts:
chart.api.Refresh()
print("Dashboard updated!")
```
### Example 2: Batch Processing Multiple Files
```python
import xlwings as xw
from pathlib import Path
def process_sales_files(folder_path, output_path):
"""Consolidate multiple Excel files into one summary."""
app = xw.App(visible=False)
app.screen_updating = False
try:
# Create summary workbook
summary_wb = xw.Book()
summary_sheet = summary_wb.sheets[0]
summary_sheet.name = 'Consolidated'
headers = ['File', 'Total Sales', 'Total Units', 'Avg Price']
summary_sheet['A1'].value = headers
row = 2
for file in Path(folder_path).glob('*.xlsx'):
wb = app.books.open(str(file))
data_sheet = wb.sheets['Sales']
# Extract summary
total_sales = data_sheet['B:B'].api.SpecialCells(11).Value # xlCellTypeConstants
total_units = data_sheet['C:C'].api.SpecialCells(11).Value
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.