Document XLSX Skill — Quick Reference
This skill enables creation, editing, and analysis of Excel spreadsheets programmatically. Claude should apply these patterns when users need to generate data reports, financial models, automate Excel workflows, or process spreadsheet data.
Modern Best Practices (Dec 2025):
- Treat spreadsheets as software: clear inputs/outputs, auditability, and versioning.
- Protect data integrity: control totals, validation, and traceability to sources.
- Accessibility and readability matter (labels, contrast, not color-only meaning).
- Ship with a review loop and an owner (avoid “mystery models”).
Quick Reference
| Task |
Tool/Library |
Language |
When to Use |
| Create XLSX |
exceljs |
Node.js |
Reports, data exports |
| Create XLSX |
openpyxl |
Python |
Formatted workbooks |
| Data analysis |
pandas |
Python |
DataFrame to Excel |
| Read XLSX |
xlsx (SheetJS) |
Node.js |
Parse spreadsheets |
| Charts |
openpyxl |
Python |
Embedded visualizations |
| Styling |
exceljs/openpyxl |
Both |
Conditional formatting |
When to Use This Skill
Claude should invoke this skill when a user requests:
- Generate Excel reports from data
- Create spreadsheets with formulas and formatting
- Add charts and pivot tables
- Parse and extract data from Excel files
- Implement conditional formatting
- Create data validation rules
- Automate Excel-based workflows
Core Operations
Create Spreadsheet (Node.js - exceljs)
import ExcelJS from 'exceljs';
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet('Sales Report');
// Headers with styling
sheet.columns = [
{ header: 'Product', key: 'product', width: 20 },
{ header: 'Quantity', key: 'qty', width: 12 },
{ header: 'Price', key: 'price', width: 12 },
{ header: 'Total', key: 'total', width: 15 },
];
// Style header row
sheet.getRow(1).font = { bold: true };
sheet.getRow(1).fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FF4472C4' }
};
// Add data
const data = [
{ product: 'Widget A', qty: 100, price: 10 },
{ product: 'Widget B', qty: 50, price: 25 },
];
data.forEach((item, index) => {
const row = sheet.addRow({
product: item.product,
qty: item.qty,
price: item.price,
total: { formula: `B${index + 2}*C${index + 2}` }
});
});
// Add totals row
const lastRow = sheet.rowCount + 1;
sheet.addRow({
product: 'TOTAL',
total: { formula: `SUM(D2:D${lastRow - 1})` }
});
// Currency formatting
sheet.getColumn('price').numFmt = '$#,##0.00';
sheet.getColumn('total').numFmt = '$#,##0.00';
await workbook.xlsx.writeFile('report.xlsx');
Create Spreadsheet (Python - openpyxl)
from openpyxl import Workbook
from openpyxl.styles import Font, Fill, PatternFill, Alignment
from openpyxl.utils import get_column_letter
from openpyxl.chart import BarChart, Reference
wb = Workbook()
ws = wb.active
ws.title = 'Sales Report'
# Headers
headers = ['Product', 'Quantity', 'Price', 'Total']
for col, header in enumerate(headers, 1):
cell = ws.cell(row=1, column=col, value=header)
cell.font = Font(bold=True, color='FFFFFF')
cell.fill = PatternFill(start_color='4472C4', fill_type='solid')
# Data
data = [
('Widget A', 100, 10),
('Widget B', 50, 25),
('Widget C', 75, 15),
]
for row_idx, (product, qty, price) in enumerate(data, 2):
ws.cell(row=row_idx, column=1, value=product)
ws.cell(row=row_idx, column=2, value=qty)
ws.cell(row=row_idx, column=3, value=price)
ws.cell(row=row_idx, column=4, value=f'=B{row_idx}*C{row_idx}')
# Totals row
total_row = len(data) + 2
ws.cell(row=total_row, column=1, value='TOTAL')
ws.cell(row=total_row, column=4, value=f'=SUM(D2:D{total_row-1})')
# Number formatting
for row in range(2, total_row + 1):
ws.cell(row=row, column=3).number_format = '$#,##0.00'
ws.cell(row=row, column=4).number_format = '$#,##0.00'
wb.save('report.xlsx')
Read and Analyze (Python - pandas)
import pandas as pd
# Read Excel file
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
# Analysis
summary = df.groupby('Category').agg({
'Sales': 'sum',
'Quantity': 'mean'
}).round(2)
# Write to Excel with formatting
with pd.ExcelWriter('analysis.xlsx', engine='openpyxl') as writer:
df.to_excel(writer, sheet_name='Raw Data', index=False)
summary.to_excel(writer, sheet_name='Summary')
# Auto-adjust column widths
for sheet in writer.sheets.values():
for column in sheet.columns:
max_length = max(len(str(cell.value)) for cell in column)
sheet.column_dimensions[column[0].column_letter].width = max_length + 2
Add Charts (Python)
from openpyxl.chart import BarChart, Reference
chart = BarChart()
chart.title = 'Sales by Product'
chart.x_axis.title = 'Product'
chart.y_axis.title = 'Sales'
# Data range
data = Reference(ws, min_col=4, min_row=1, max_row=len(data)+1, max_col=4)
categories = Reference(ws, min_col=1, min_row=2, max_row=len(data)+1)
chart.add_data(data, titles_from_data=True)
chart.set_categories(categories)
chart.shape = 4
ws.add_chart(chart, 'F2')
Conditional Formatting
from openpyxl.formatting.rule import ColorScaleRule, FormulaRule
from openpyxl.styles import PatternFill
# Color scale (heatmap)
ws.conditional_formatting.add(
'D2:D100',
ColorScaleRule(
start_type='min', start_color='FF0000',
end_type='max', end_color='00FF00'
)
)
# Highlight cells above threshold
red_fill = PatternFill(start_color='FFCCCC', fill_type='solid')
ws.conditional_formatting.add(
'D2:D100',
FormulaRule(formula=['D2>1000'], fill=red_fill)
)
Common Formulas Reference
| Purpose |
Formula |
Example |
| Sum |
=SUM(range) |
=SUM(A1:A10) |
| Average |
=AVERAGE(range) |
=AVERAGE(B2:B100) |
| Count |
=COUNT(range) |
=COUNT(C:C) |
| Conditional sum |
=SUMIF(range,criteria,sum_range) |
=SUMIF(A:A,"Widget",B:B) |
| Lookup |
=VLOOKUP(value,range,col,FALSE) |
=VLOOKUP(A2,Data!A:C,3,FALSE) |
| If |
=IF(condition,true,false) |
=IF(B2>100,"High","Low") |
| Percentage |
=value/total |
=B2/SUM(B:B) |
Decision Tree
Excel Task: [What do you need?]
├─ Create new spreadsheet?
│ ├─ Simple data export → pandas to_excel()
│ ├─ Formatted report → exceljs or openpyxl
│ └─ With charts → openpyxl charts module
│
├─ Read/analyze existing?
│ ├─ Data analysis → pandas read_excel()
│ ├─ Preserve formatting → openpyxl load_workbook()
│ └─ Fast parsing → xlsx (SheetJS)
│
├─ Modify existing?
│ ├─ Add data → openpyxl (preserves formatting)
│ └─ Update formulas → openpyxl
│
└─ Complex features?
├─ Pivot tables → openpyxl or xlwings
├─ Data validation → openpyxl DataValidation
└─ Macros → xlwings (Python-Excel bridge)
Do / Avoid (Dec 2025)
Do
- Separate Inputs / Calculations / Outputs (tabs or clear sections).
- Keep assumptions explicit (value + unit + source + date).
- Add control totals and reconciliation checks for imported data.
Avoid
- Hardcoded constants inside formulas without a documented assumption.
- Hidden rows/columns that change results without documentation.
- Sharing sheets with customer PII or secrets.
What Good Looks Like
- Structure: clear Inputs/Assumptions, Calculations, and Outputs separation (tabs or sections).
- Integrity: no
#REF!, broken named ranges, or hardcoded constants hidden in formulas.
- Traceability: every key output ties back to labeled inputs (units + source + date).
- Checks: control totals, reconciliations, and error flags that fail loudly.
- Review: independent review pass using
templates/spreadsheet-model-review-checklist.md.
Optional: AI / Automation
Use only when explicitly requested and policy-compliant.
- Generate first-pass formulas/charts; humans verify correctness and edge cases.
- Draft documentation tabs (assumptions, glossary); do not invent source data.
Navigation
Resources
- resources/excel-formulas.md — Formula reference and patterns
- resources/excel-formatting.md — Styling, conditional formatting
- resources/excel-charts.md — Chart types and customization
- data/sources.json — Library documentation links
Templates
- templates/financial-report.md — Financial statement template
- templates/data-dashboard.md — Dashboard with charts
- templates/spreadsheet-model-review-checklist.md — Model QA checklist (assumptions, formulas, traceability)
Related Skills
1---2name: document-xlsx3description: Create, edit, and analyze Excel spreadsheets with formulas, formatting, charts, pivot tables, and data validation. Supports xlsx, exceljs, openpyxl, and pandas for comprehensive spreadsheet workflows in Node.js and Python.4---5
6# Document XLSX Skill — Quick Reference
7
8This skill enables creation, editing, and analysis of Excel spreadsheets programmatically. Claude should apply these patterns when users need to generate data reports, financial models, automate Excel workflows, or process spreadsheet data.
9
10**Modern Best Practices (Dec 2025)**:
11- Treat spreadsheets as software: clear inputs/outputs, auditability, and versioning.
12- Protect data integrity: control totals, validation, and traceability to sources.
13- Accessibility and readability matter (labels, contrast, not color-only meaning).
14- Ship with a review loop and an owner (avoid “mystery models”).
15
16---
17
18## Quick Reference
19
20| Task | Tool/Library | Language | When to Use |
21|------|--------------|----------|-------------|
22| Create XLSX | exceljs | Node.js | Reports, data exports |
23| Create XLSX | openpyxl | Python | Formatted workbooks |
24| Data analysis | pandas | Python | DataFrame to Excel |
25| Read XLSX | xlsx (SheetJS) | Node.js | Parse spreadsheets |
26| Charts | openpyxl | Python | Embedded visualizations |
27| Styling | exceljs/openpyxl | Both | Conditional formatting |
28
29## When to Use This Skill
30
31Claude should invoke this skill when a user requests:
32
33- Generate Excel reports from data
34- Create spreadsheets with formulas and formatting
35- Add charts and pivot tables
36- Parse and extract data from Excel files
37- Implement conditional formatting
38- Create data validation rules
39- Automate Excel-based workflows
40
41---
42
43## Core Operations
44
45### Create Spreadsheet (Node.js - exceljs)
46
47```typescript
48import ExcelJS from 'exceljs';
49
50const workbook = new ExcelJS.Workbook();
51const sheet = workbook.addWorksheet('Sales Report');
52
53// Headers with styling
54sheet.columns = [
55 { header: 'Product', key: 'product', width: 20 },
56 { header: 'Quantity', key: 'qty', width: 12 },
57 { header: 'Price', key: 'price', width: 12 },
58 { header: 'Total', key: 'total', width: 15 },
59];
60
61// Style header row
62sheet.getRow(1).font = { bold: true };
63sheet.getRow(1).fill = {
64 type: 'pattern',
65 pattern: 'solid',
66 fgColor: { argb: 'FF4472C4' }
67};
68
69// Add data
70const data = [
71 { product: 'Widget A', qty: 100, price: 10 },
72 { product: 'Widget B', qty: 50, price: 25 },
73];
74
75data.forEach((item, index) => {
76 const row = sheet.addRow({
77 product: item.product,
78 qty: item.qty,
79 price: item.price,
80 total: { formula: `B${index + 2}*C${index + 2}` }
81 });
82});
83
84// Add totals row
85const lastRow = sheet.rowCount + 1;
86sheet.addRow({
87 product: 'TOTAL',
88 total: { formula: `SUM(D2:D${lastRow - 1})` }
89});
90
91// Currency formatting
92sheet.getColumn('price').numFmt = '$#,##0.00';
93sheet.getColumn('total').numFmt = '$#,##0.00';
94
95await workbook.xlsx.writeFile('report.xlsx');
96```
97
98### Create Spreadsheet (Python - openpyxl)
99
100```python
101from openpyxl import Workbook
102from openpyxl.styles import Font, Fill, PatternFill, Alignment
103from openpyxl.utils import get_column_letter
104from openpyxl.chart import BarChart, Reference
105
106wb = Workbook()
107ws = wb.active
108ws.title = 'Sales Report'
109
110# Headers
111headers = ['Product', 'Quantity', 'Price', 'Total']
112for col, header in enumerate(headers, 1):
113 cell = ws.cell(row=1, column=col, value=header)
114 cell.font = Font(bold=True, color='FFFFFF')
115 cell.fill = PatternFill(start_color='4472C4', fill_type='solid')
116
117# Data
118data = [
119 ('Widget A', 100, 10),
120 ('Widget B', 50, 25),
121 ('Widget C', 75, 15),
122]
123
124for row_idx, (product, qty, price) in enumerate(data, 2):
125 ws.cell(row=row_idx, column=1, value=product)
126 ws.cell(row=row_idx, column=2, value=qty)
127 ws.cell(row=row_idx, column=3, value=price)
128 ws.cell(row=row_idx, column=4, value=f'=B{row_idx}*C{row_idx}')
129
130# Totals row
131total_row = len(data) + 2
132ws.cell(row=total_row, column=1, value='TOTAL')
133ws.cell(row=total_row, column=4, value=f'=SUM(D2:D{total_row-1})')
134
135# Number formatting
136for row in range(2, total_row + 1):
137 ws.cell(row=row, column=3).number_format = '$#,##0.00'
138 ws.cell(row=row, column=4).number_format = '$#,##0.00'
139
140wb.save('report.xlsx')
141```
142
143### Read and Analyze (Python - pandas)
144
145```python
146import pandas as pd
147
148# Read Excel file
149df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
150
151# Analysis
152summary = df.groupby('Category').agg({
153 'Sales': 'sum',
154 'Quantity': 'mean'
155}).round(2)
156
157# Write to Excel with formatting
158with pd.ExcelWriter('analysis.xlsx', engine='openpyxl') as writer:
159 df.to_excel(writer, sheet_name='Raw Data', index=False)
160 summary.to_excel(writer, sheet_name='Summary')
161
162 # Auto-adjust column widths
163 for sheet in writer.sheets.values():
164 for column in sheet.columns:
165 max_length = max(len(str(cell.value)) for cell in column)
166 sheet.column_dimensions[column[0].column_letter].width = max_length + 2
167```
168
169### Add Charts (Python)
170
171```python
172from openpyxl.chart import BarChart, Reference
173
174chart = BarChart()
175chart.title = 'Sales by Product'
176chart.x_axis.title = 'Product'
177chart.y_axis.title = 'Sales'
178
179# Data range
180data = Reference(ws, min_col=4, min_row=1, max_row=len(data)+1, max_col=4)
181categories = Reference(ws, min_col=1, min_row=2, max_row=len(data)+1)
182
183chart.add_data(data, titles_from_data=True)
184chart.set_categories(categories)
185chart.shape = 4
186
187ws.add_chart(chart, 'F2')
188```
189
190### Conditional Formatting
191
192```python
193from openpyxl.formatting.rule import ColorScaleRule, FormulaRule
194from openpyxl.styles import PatternFill
195
196# Color scale (heatmap)
197ws.conditional_formatting.add(
198 'D2:D100',
199 ColorScaleRule(
200 start_type='min', start_color='FF0000',
201 end_type='max', end_color='00FF00'
202 )
203)
204
205# Highlight cells above threshold
206red_fill = PatternFill(start_color='FFCCCC', fill_type='solid')
207ws.conditional_formatting.add(
208 'D2:D100',
209 FormulaRule(formula=['D2>1000'], fill=red_fill)
210)
211```
212
213---
214
215## Common Formulas Reference
216
217| Purpose | Formula | Example |
218|---------|---------|---------|
219| Sum | `=SUM(range)` | `=SUM(A1:A10)` |
220| Average | `=AVERAGE(range)` | `=AVERAGE(B2:B100)` |
221| Count | `=COUNT(range)` | `=COUNT(C:C)` |
222| Conditional sum | `=SUMIF(range,criteria,sum_range)` | `=SUMIF(A:A,"Widget",B:B)` |
223| Lookup | `=VLOOKUP(value,range,col,FALSE)` | `=VLOOKUP(A2,Data!A:C,3,FALSE)` |
224| If | `=IF(condition,true,false)` | `=IF(B2>100,"High","Low")` |
225| Percentage | `=value/total` | `=B2/SUM(B:B)` |
226
227---
228
229## Decision Tree
230
231```text
232Excel Task: [What do you need?]
233 ├─ Create new spreadsheet?
234 │ ├─ Simple data export → pandas to_excel()
235 │ ├─ Formatted report → exceljs or openpyxl
236 │ └─ With charts → openpyxl charts module
237 │
238 ├─ Read/analyze existing?
239 │ ├─ Data analysis → pandas read_excel()
240 │ ├─ Preserve formatting → openpyxl load_workbook()
241 │ └─ Fast parsing → xlsx (SheetJS)
242 │
243 ├─ Modify existing?
244 │ ├─ Add data → openpyxl (preserves formatting)
245 │ └─ Update formulas → openpyxl
246 │
247 └─ Complex features?
248 ├─ Pivot tables → openpyxl or xlwings
249 ├─ Data validation → openpyxl DataValidation
250 └─ Macros → xlwings (Python-Excel bridge)
251```
252
253---
254
255## Do / Avoid (Dec 2025)
256
257### Do
258
259- Separate Inputs / Calculations / Outputs (tabs or clear sections).
260- Keep assumptions explicit (value + unit + source + date).
261- Add control totals and reconciliation checks for imported data.
262
263### Avoid
264
265- Hardcoded constants inside formulas without a documented assumption.
266- Hidden rows/columns that change results without documentation.
267- Sharing sheets with customer PII or secrets.
268
269## What Good Looks Like
270
271- Structure: clear Inputs/Assumptions, Calculations, and Outputs separation (tabs or sections).
272- Integrity: no `#REF!`, broken named ranges, or hardcoded constants hidden in formulas.
273- Traceability: every key output ties back to labeled inputs (units + source + date).
274- Checks: control totals, reconciliations, and error flags that fail loudly.
275- Review: independent review pass using `templates/spreadsheet-model-review-checklist.md`.
276
277## Optional: AI / Automation
278
279Use only when explicitly requested and policy-compliant.
280
281- Generate first-pass formulas/charts; humans verify correctness and edge cases.
282- Draft documentation tabs (assumptions, glossary); do not invent source data.
283
284## Navigation
285
286**Resources**
287- [resources/excel-formulas.md](resources/excel-formulas.md) — Formula reference and patterns
288- [resources/excel-formatting.md](resources/excel-formatting.md) — Styling, conditional formatting
289- [resources/excel-charts.md](resources/excel-charts.md) — Chart types and customization
290- [data/sources.json](data/sources.json) — Library documentation links
291
292**Templates**
293- [templates/financial-report.md](templates/financial-report.md) — Financial statement template
294- [templates/data-dashboard.md](templates/data-dashboard.md) — Dashboard with charts
295- [templates/spreadsheet-model-review-checklist.md](templates/spreadsheet-model-review-checklist.md) — Model QA checklist (assumptions, formulas, traceability)
296
297**Related Skills**
298- [../document-pdf/SKILL.md](../document-pdf/SKILL.md) — PDF generation from data
299- [../ai-ml-data-science/SKILL.md](../ai-ml-data-science/SKILL.md) — Data analysis patterns
300- [../data-sql-optimization/SKILL.md](../data-sql-optimization/SKILL.md) — Database to Excel workflows