Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
.claude/skills/kxiandaoyan-xlsx/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 107% | 0% |
| case-20 | ✗→✓ | ▲ Improved | 82% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 65% | 0% |
| case-07 | ✓→✓ | = Same ✓ | 71% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 202% | 0% |
> ⚠️ OUTPUT PATH RULE: All generated XLSX files MUST be saved to /shared/ directory (e.g., /shared/report.xlsx, /shared/output/data.xlsx). NEVER save to /data/. Only files in /shared/ are accessible to the user.
Unless otherwise stated by the user or existing template
A user may ask you to create, edit, or analyze the contents of an .xlsx file. You have different tools and workflows available for different tasks.
LibreOffice Required for Formula Recalculation: You can assume LibreOffice is installed for recalculating formula values using the recalc.py script. The script automatically configures LibreOffice on first run
For data analysis, visualization, and basic operations, use pandas which provides powerful data manipulation capabilities:
pythonimport pandas as pd # Read Excel df = pd.read_excel('file.xlsx') # Default: first sheet all_sheets = pd.read_excel('file.xlsx', sheet_name=None) # All sheets as dict # Analyze df.head() # Preview data df.info() # Column info df.describe() # Statistics # Write Excel df.to_excel('output.xlsx', index=False)
Always use Excel formulas instead of calculating values in Python and hardcoding them. This ensures the spreadsheet remains dynamic and updateable.
python# Bad: Calculating in Python and hardcoding result total = df['Sales'].sum() sheet['B10'] = total # Hardcodes 5000 # Bad: Computing growth rate in Python growth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue'] sheet['C5'] = growth # Hardcodes 0.15 # Bad: Python calculation for average avg = sum(values) / len(values) sheet['D20'] = avg # Hardcodes 42.5
python# Good: Let Excel calculate the sum sheet['B10'] = '=SUM(B2:B9)' # Good: Growth rate as Excel formula sheet['C5'] = '=(C4-C2)/C2' # Good: Average using Excel function sheet['D20'] = '=AVERAGE(D2:D19)'
This applies to ALL calculations - totals, percentages, ratios, differences, etc. The spreadsheet should be able to recalculate when source data changes.
bash python recalc.py output.xlsx
status is errors_found, check error_summary for specific error types and locations#REF!: Invalid cell references#DIV/0!: Division by zero#VALUE!: Wrong data type in formula#NAME?: Unrecognized formula namepython# Using openpyxl for formulas and formatting from openpyxl import Workbook from openpyxl.styles import Font, PatternFill, Alignment wb = Workbook() sheet = wb.active # Add data sheet['A1'] = 'Hello' sheet['B1'] = 'World' sheet.append(['Row', 'of', 'data']) # Add formula sheet['B2'] = '=SUM(A1:A10)' # Formatting sheet['A1'].font = Font(bold=True, color='FF0000') sheet['A1'].fill = PatternFill('solid', start_color='FFFF00') sheet['A1'].alignment = Alignment(horizontal='center') # Column width sheet.column_dimensions['A'].width = 20 wb.save('output.xlsx')
python# Using openpyxl to preserve formulas and formatting from openpyxl import load_workbook # Load existing file wb = load_workbook('existing.xlsx') sheet = wb.active # or wb['SheetName'] for specific sheet # Working with multiple sheets for sheet_name in wb.sheetnames: sheet = wb[sheet_name] print(f"Sheet: {sheet_name}") # Modify cells sheet['A1'] = 'New Value' sheet.insert_rows(2) # Insert row at position 2 sheet.delete_cols(3) # Delete column 3 # Add new sheet new_sheet = wb.create_sheet('NewSheet') new_sheet['A1'] = 'Data' wb.save('modified.xlsx')
Excel files created or modified by openpyxl contain formulas as strings but not calculated values. Use the provided recalc.py script to recalculate formulas:
bashpython recalc.py <excel_file> [timeout_seconds]
Example:
bashpython recalc.py output.xlsx 30
The script:
Quick checks to ensure formulas work correctly:
pd.notna()/ in formulas (#DIV/0!)The script returns JSON with error details:
json{ "status": "success", // or "errors_found" "total_errors": 0, // Total error count "total_formulas": 42, // Number of formulas in file "error_summary": { // Only present if errors found "#REF!": { "count": 2, "locations": ["Sheet1!B5", "Sheet1!C10"] } } }
data_only=True to read calculated values: load_workbook('file.xlsx', data_only=True)data_only=True and saved, formulas are replaced with values and permanently lostread_only=True for reading or write_only=True for writingpd.read_excel('file.xlsx', dtype={'id': str})pd.read_excel('file.xlsx', usecols=['A', 'C', 'E'])pd.read_excel('file.xlsx', parse_dates=['date_column'])IMPORTANT: When generating Python code for Excel operations:
For Excel files themselves:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-07 | pass→pass | 12,380 | 6,439 | -48% | 1 | 1 | 0% | 2,324 | 3,974 | +71% | 0 | 0 | — |
case-01 | fail→fail | 28,203 | 55,885 | +98% | 1 | 1 | 0% | 6,224 | 9,014 | +45% | 0 | 0 | — |
case-02 | fail→fail | 27,071 | 21,389 | -21% | 1 | 1 | 0% | 6,206 | 3,972 | -36% | 0 | 0 | — |
case-03 | pass→pass | 8,059 | 8,068 | +0% | 1 | 1 | 0% | 1,478 | 4,469 | +202% | 0 | 0 | — |
case-04 | pass→pass | 12,085 | 11,174 | -8% | 1 | 1 | 0% | 2,296 | 4,892 | +113% | 0 | 0 | — |
case-05 | pass→pass | 6,179 | 7,157 | +16% | 1 | 1 | 0% | 1,125 | 4,164 | +270% | 0 | 0 | — |
case-06 | fail→pass | 17,762 | 20,677 | +16% | 1 | 1 | 0% | 3,604 | 7,445 | +107% | 0 | 0 | — |
case-08 | pass→pass | 5,989 | 3,587 | -40% | 1 | 1 | 0% | 1,143 | 3,439 | +201% | 0 | 0 | — |
case-09 | pass→pass | 8,950 | 7,522 | -16% | 1 | 1 | 0% | 1,595 | 4,193 | +163% | 0 | 0 | — |
case-10 | pass→pass | 7,148 | 4,594 | -36% | 1 | 1 | 0% | 1,336 | 3,487 | +161% | 0 | 0 | — |
case-11 | pass→pass | 16,860 | 9,359 | -44% | 1 | 1 | 0% | 2,950 | 4,435 | +50% | 0 | 0 | — |
case-12 | pass→pass | 11,804 | 7,962 | -33% | 1 | 1 | 0% | 1,972 | 4,176 | +112% | 0 | 0 | — |
case-13 | pass→pass | 12,425 | 6,544 | -47% | 1 | 1 | 0% | 2,062 | 4,000 | +94% | 0 | 0 | — |
case-14 | pass→pass | 10,664 | 6,874 | -36% | 1 | 1 | 0% | 1,804 | 3,851 | +113% | 0 | 0 | — |
case-15 | pass→pass | 11,305 | 7,023 | -38% | 1 | 1 | 0% | 2,146 | 4,151 | +93% | 0 | 0 | — |
case-16 | pass→pass | 16,824 | 3,643 | -78% | 1 | 1 | 0% | 2,925 | 3,430 | +17% | 0 | 0 | — |
case-17 | pass→pass | 11,063 | 3,106 | -72% | 1 | 1 | 0% | 1,680 | 3,299 | +96% | 0 | 0 | — |
case-18 | fail→fail | 8,196 | 1,951 | -76% | 1 | 1 | 0% | 1,358 | 3,081 | +127% | 0 | 0 | — |
case-19 | pass→pass | 10,499 | 2,198 | -79% | 1 | 1 | 0% | 1,645 | 3,093 | +88% | 0 | 0 | — |
case-20 | fail→pass | 13,345 | 7,209 | -46% | 1 | 1 | 0% | 2,198 | 4,009 | +82% | 0 | 0 | — |
case-21 | pass→pass | 10,057 | 6,064 | -40% | 1 | 1 | 0% | 1,690 | 3,798 | +125% | 0 | 0 | — |
case-22 | fail→pass | 12,553 | 3,383 | -73% | 1 | 1 | 0% | 2,053 | 3,392 | +65% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +14 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.