XLSX creation, editing, and analysis
Execution Rules
- ALL code execution MUST use the
code_interpreter tool. Do NOT use the shell tool.
- NEVER call
!pip install. openpyxl, pandas, boto3, numpy, Pillow, matplotlib, lxml are pre-installed in the AgentCore Code Interpreter sandbox. Import directly. If an import fails, stop and report the error to the user — do not attempt to install anything.
- Generate the COMPLETE spreadsheet and upload to S3 in a SINGLE
code_interpreter call. Do NOT split into multiple calls.
- Before calling
code_interpreter, call artifact_path(filename="spreadsheet.xlsx") to get the S3 bucket and key.
- After completion, report the
artifact_ref to the user.
- If
code_interpreter fails with an error, do NOT retry automatically. Report the error to the user and ask for clarification or guidance. Do not make multiple retry attempts without user input.
Workflow
- Call
artifact_path(filename="spreadsheet.xlsx") — returns { s3_uri, bucket, key, artifact_ref }
- Copy the actual
s3_uri string value from the artifact_path result and hardcode it as a string literal in your code_interpreter script. Do NOT use variable references — the code_interpreter runs in an isolated sandbox and cannot access the agent's tool results.
- Call
code_interpreter ONCE with a single script that does everything: create the spreadsheet, save it, and upload to S3.
from openpyxl import Workbook
import boto3
# IMPORTANT: Replace with the ACTUAL s3_uri value returned by artifact_path
S3_URI = "s3://my-bucket/user123/proj456/artifacts/art_abc123/spreadsheet.xlsx" # ← paste the actual s3_uri here
# Parse S3 URI into bucket and key
BUCKET, KEY = S3_URI.replace("s3://", "").split("/", 1)
# Build entire spreadsheet
wb = Workbook()
# ... all spreadsheet content ...
wb.save('./output.xlsx')
# Upload to S3
s3 = boto3.client('s3')
with open('./output.xlsx', 'rb') as f:
s3.upload_fileobj(
f, BUCKET, KEY,
ExtraArgs={'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}
)
- Report the
artifact_ref to the user
Quick Reference
| Task |
Approach |
| Read/analyze content |
Download from S3 → pandas or openpyxl in code_interpreter |
| Create new spreadsheet |
Use openpyxl in code_interpreter |
| Edit existing spreadsheet |
Download from S3 → openpyxl → edit → upload in code_interpreter |
Charts
When the user requests charts or visualizations, always attempt to embed charts directly using openpyxl first. Only use the chart skill if direct embedding is not possible or the chart type is unsupported by openpyxl.
from openpyxl.chart import BarChart, Reference
chart = BarChart()
data = Reference(sheet, min_col=2, min_row=1, max_row=5)
chart.add_data(data, titles_from_data=True)
sheet.add_chart(chart, "E2")
Chart QA — Overlap Detection
After generating the file, run this check to catch overlapping charts before uploading:
from openpyxl import load_workbook
from openpyxl.drawing.spreadsheet_drawing import TwoCellAnchor, OneCellAnchor
# Approximate EMU per default cell (column width ~8.43 chars, row height ~15pt)
EMU_PER_COL = 600000
EMU_PER_ROW = 190500
def _bounds(anchor):
if isinstance(anchor, TwoCellAnchor):
return (anchor._from.col, anchor._from.row, anchor.to.col, anchor.to.row)
if isinstance(anchor, OneCellAnchor):
c, r = anchor._from.col, anchor._from.row
return (c, r, c + round(anchor.ext.cx / EMU_PER_COL), r + round(anchor.ext.cy / EMU_PER_ROW))
return None
def _overlaps(a, b):
return not (a[2] <= b[0] or b[2] <= a[0] or a[3] <= b[1] or b[3] <= a[1])
wb = load_workbook('./output.xlsx')
issues = []
for ws in wb.worksheets:
bounds = [(c, _bounds(c.anchor)) for c in ws._charts]
bounds = [(c, b) for c, b in bounds if b]
for i, (_, b1) in enumerate(bounds):
for _, b2 in bounds[i+1:]:
if _overlaps(b1, b2):
issues.append(f"Sheet '{ws.title}': chart overlap {b1} ↔ {b2}")
if issues:
for issue in issues:
print(f"OVERLAP: {issue}")
raise ValueError("Fix chart positions before uploading")
else:
print("OK: no chart overlaps")
If overlaps are detected, adjust the anchor cell or set an explicit size:
from openpyxl.drawing.spreadsheet_drawing import TwoCellAnchor
from openpyxl.drawing.xdr import XDRPoint2D, XDRPositiveSize2D
from openpyxl.utils.units import pixels_to_EMU
# Place chart at E2, spanning to O17 (no overlap with next chart starting at E19)
chart.anchor = "E2:O17"
Requirements for Outputs
All Excel files
Professional Font
- Use a consistent, professional font (e.g., Arial, Times New Roman) for all deliverables unless otherwise instructed by the user
Zero Formula Errors
- Every Excel model MUST be delivered with ZERO formula errors (#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?)
Preserve Existing Templates (when updating templates)
- Study and EXACTLY match existing format, style, and conventions when modifying files
- Never impose standardized formatting on files with established patterns
- Existing template conventions ALWAYS override these guidelines
Financial models
Color Coding Standards
Unless otherwise stated by the user or existing template
Industry-Standard Color Conventions
- Blue text (RGB: 0,0,255): Hardcoded inputs, and numbers users will change for scenarios
- Black text (RGB: 0,0,0): ALL formulas and calculations
- Green text (RGB: 0,128,0): Links pulling from other worksheets within same workbook
- Red text (RGB: 255,0,0): External links to other files
- Yellow background (RGB: 255,255,0): Key assumptions needing attention or cells that need to be updated
Number Formatting Standards
Required Format Rules
- Years: Format as text strings (e.g., "2024" not "2,024")
- Currency: Use $#,##0 format; ALWAYS specify units in headers ("Revenue ($mm)")
- Zeros: Use number formatting to make all zeros "-", including percentages (e.g., "$#,##0;($#,##0);-")
- Percentages: Default to 0.0% format (one decimal)
- Multiples: Format as 0.0x for valuation multiples (EV/EBITDA, P/E)
- Negative numbers: Use parentheses (123) not minus -123
Formula Construction Rules
Assumptions Placement
- Place ALL assumptions (growth rates, margins, multiples, etc.) in separate assumption cells
- Use cell references instead of hardcoded values in formulas
- Example: Use =B5*(1+$B$6) instead of =B5*1.05
Formula Error Prevention
- Verify all cell references are correct
- Check for off-by-one errors in ranges
- Ensure consistent formulas across all projection periods
- Test with edge cases (zero values, negative numbers)
- Verify no unintended circular references
Reading and analyzing data
Read .xlsx files by downloading from the given S3 path and using tools in code_interpreter.
Data analysis with pandas
import boto3
import pandas as pd
s3 = boto3.client('s3')
s3.download_file(bucket, key, 'spreadsheet.xlsx')
df = pd.read_excel('spreadsheet.xlsx') # Default: first sheet
all_sheets = pd.read_excel('spreadsheet.xlsx', sheet_name=None) # All sheets as dict
df.head() # Preview data
df.info() # Column info
df.describe() # Statistics
Excel File Workflows
CRITICAL: Use Formulas, Not Hardcoded Values
Always use Excel formulas instead of calculating values in Python and hardcoding them. This ensures the spreadsheet remains dynamic and updateable.
❌ WRONG - Hardcoding Calculated Values
total = df['Sales'].sum()
sheet['B10'] = total # Hardcodes 5000
growth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue']
sheet['C5'] = growth # Hardcodes 0.15
✅ CORRECT - Using Excel Formulas
sheet['B10'] = '=SUM(B2:B9)'
sheet['C5'] = '=(C4-C2)/C2'
Formulas are stored as strings by openpyxl and recalculated automatically when the user opens the file in Excel or LibreOffice Calc.
Common Workflow
- Choose tool: pandas for data, openpyxl for formulas/formatting
- Create/Load: Create new workbook or load existing file
- Modify: Add/edit data, formulas, and formatting
- Save: Write to file
- Upload: Upload to S3
Creating new Excel files
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
import boto3
wb = Workbook()
sheet = wb.active
sheet['A1'] = 'Hello'
sheet['B1'] = 'World'
sheet.append(['Row', 'of', 'data'])
sheet['B2'] = '=SUM(A1:A10)'
sheet['A1'].font = Font(bold=True, color='FF0000')
sheet['A1'].fill = PatternFill('solid', start_color='FFFF00')
sheet['A1'].alignment = Alignment(horizontal='center')
sheet.column_dimensions['A'].width = 20
wb.save('./output.xlsx')
# Upload to S3
s3 = boto3.client('s3')
with open('./output.xlsx', 'rb') as f:
s3.upload_fileobj(
f, BUCKET, KEY,
ExtraArgs={'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}
)
Editing existing Excel files
from openpyxl import load_workbook
import boto3
# Download from S3
s3 = boto3.client('s3')
s3.download_file(bucket, key, 'existing.xlsx')
wb = load_workbook('existing.xlsx')
sheet = wb.active # or wb['SheetName'] for specific sheet
for sheet_name in wb.sheetnames:
sheet = wb[sheet_name]
sheet['A1'] = 'New Value'
sheet.insert_rows(2)
sheet.delete_cols(3)
new_sheet = wb.create_sheet('NewSheet')
new_sheet['A1'] = 'Data'
wb.save('./modified.xlsx')
# Upload to S3
with open('./modified.xlsx', 'rb') as f:
s3.upload_fileobj(
f, BUCKET, KEY,
ExtraArgs={'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}
)
Best Practices
Library Selection
- pandas: Best for data analysis, bulk operations, and simple data export
- openpyxl: Best for complex formatting, formulas, and Excel-specific features
Working with openpyxl
- Cell indices are 1-based (row=1, column=1 refers to cell A1)
- Use
data_only=True to read cached values from existing files: load_workbook('file.xlsx', data_only=True)
- Note: openpyxl-generated files do not have cached formula values — formulas recalculate when opened in Excel/LibreOffice Calc
- For large files: Use
read_only=True for reading or write_only=True for writing
Working with pandas
- Specify data types to avoid inference issues:
pd.read_excel('file.xlsx', dtype={'id': str})
- For large files, read specific columns:
pd.read_excel('file.xlsx', usecols=['A', 'C', 'E'])
- Handle dates properly:
pd.read_excel('file.xlsx', parse_dates=['date_column'])
Code Style Guidelines
IMPORTANT: When generating Python code for Excel operations:
- Write minimal, concise Python code without unnecessary comments
- Avoid verbose variable names and redundant operations
- Avoid unnecessary print statements
For Excel files themselves:
- Document data sources for hardcoded values
- Include notes for key calculations and model sections
Dependencies
openpyxl, pandas, boto3, numpy, Pillow, matplotlib are pre-installed in the Code Interpreter sandbox. Do NOT call !pip install — import directly.
1---2name: xlsx3description: Excel spreadsheet (.xlsx) creation, editing, reading, and manipulation skill. Use when the user wants to create, read, edit, or manipulate Excel spreadsheets (.xlsx, .xlsm, .csv, .tsv files). Triggers include: any mention of 'spreadsheet', 'Excel', '.xlsx', or requests for tabular data deliverables. Also for adding columns, computing formulas, formatting, charting, cleaning messy data, or converting between tabular file formats. When an S3 URI with .xlsx extension is provided. Do NOT use for PDFs, Word documents, or Google Sheets.4---56# XLSX creation, editing, and analysis78## Execution Rules910- **ALL code execution MUST use the `code_interpreter` tool.** Do NOT use the `shell` tool.11- **NEVER call `!pip install`.** `openpyxl`, `pandas`, `boto3`, `numpy`, `Pillow`, `matplotlib`, `lxml` are pre-installed in the AgentCore Code Interpreter sandbox. Import directly. If an import fails, stop and report the error to the user — do not attempt to install anything.12- **Generate the COMPLETE spreadsheet and upload to S3 in a SINGLE `code_interpreter` call.** Do NOT split into multiple calls.13- Before calling `code_interpreter`, call `artifact_path(filename="spreadsheet.xlsx")` to get the S3 bucket and key.14- After completion, report the `artifact_ref` to the user.15- **If `code_interpreter` fails with an error, do NOT retry automatically.** Report the error to the user and ask for clarification or guidance. Do not make multiple retry attempts without user input.1617### Workflow18191. Call `artifact_path(filename="spreadsheet.xlsx")` — returns `{ s3_uri, bucket, key, artifact_ref }`202. **Copy the actual `s3_uri` string value** from the artifact_path result and **hardcode it as a string literal** in your code_interpreter script. Do NOT use variable references — the code_interpreter runs in an isolated sandbox and cannot access the agent's tool results.213. Call `code_interpreter` ONCE with a single script that does everything: create the spreadsheet, save it, and upload to S3.2223```python24from openpyxl import Workbook25import boto32627# IMPORTANT: Replace with the ACTUAL s3_uri value returned by artifact_path28S3_URI = "s3://my-bucket/user123/proj456/artifacts/art_abc123/spreadsheet.xlsx" # ← paste the actual s3_uri here2930# Parse S3 URI into bucket and key31BUCKET, KEY = S3_URI.replace("s3://", "").split("/", 1)3233# Build entire spreadsheet34wb = Workbook()35# ... all spreadsheet content ...36wb.save('./output.xlsx')3738# Upload to S339s3 = boto3.client('s3')40with open('./output.xlsx', 'rb') as f:41 s3.upload_fileobj(42 f, BUCKET, KEY,43 ExtraArgs={'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}44 )45```464. Report the `artifact_ref` to the user4748---4950## Quick Reference5152| Task | Approach |53|------|----------|54| Read/analyze content | Download from S3 → `pandas` or `openpyxl` in code_interpreter |55| Create new spreadsheet | Use `openpyxl` in code_interpreter |56| Edit existing spreadsheet | Download from S3 → `openpyxl` → edit → upload in code_interpreter |5758## Charts5960**When the user requests charts or visualizations, always attempt to embed charts directly using `openpyxl` first.** Only use the `chart` skill if direct embedding is not possible or the chart type is unsupported by openpyxl.6162```python63from openpyxl.chart import BarChart, Reference6465chart = BarChart()66data = Reference(sheet, min_col=2, min_row=1, max_row=5)67chart.add_data(data, titles_from_data=True)68sheet.add_chart(chart, "E2")69```7071### Chart QA — Overlap Detection7273After generating the file, run this check to catch overlapping charts before uploading:7475```python76from openpyxl import load_workbook77from openpyxl.drawing.spreadsheet_drawing import TwoCellAnchor, OneCellAnchor7879# Approximate EMU per default cell (column width ~8.43 chars, row height ~15pt)80EMU_PER_COL = 60000081EMU_PER_ROW = 1905008283def _bounds(anchor):84 if isinstance(anchor, TwoCellAnchor):85 return (anchor._from.col, anchor._from.row, anchor.to.col, anchor.to.row)86 if isinstance(anchor, OneCellAnchor):87 c, r = anchor._from.col, anchor._from.row88 return (c, r, c + round(anchor.ext.cx / EMU_PER_COL), r + round(anchor.ext.cy / EMU_PER_ROW))89 return None9091def _overlaps(a, b):92 return not (a[2] <= b[0] or b[2] <= a[0] or a[3] <= b[1] or b[3] <= a[1])9394wb = load_workbook('./output.xlsx')95issues = []96for ws in wb.worksheets:97 bounds = [(c, _bounds(c.anchor)) for c in ws._charts]98 bounds = [(c, b) for c, b in bounds if b]99 for i, (_, b1) in enumerate(bounds):100 for _, b2 in bounds[i+1:]:101 if _overlaps(b1, b2):102 issues.append(f"Sheet '{ws.title}': chart overlap {b1} ↔ {b2}")103104if issues:105 for issue in issues:106 print(f"OVERLAP: {issue}")107 raise ValueError("Fix chart positions before uploading")108else:109 print("OK: no chart overlaps")110```111112If overlaps are detected, adjust the anchor cell or set an explicit size:113114```python115from openpyxl.drawing.spreadsheet_drawing import TwoCellAnchor116from openpyxl.drawing.xdr import XDRPoint2D, XDRPositiveSize2D117from openpyxl.utils.units import pixels_to_EMU118119# Place chart at E2, spanning to O17 (no overlap with next chart starting at E19)120chart.anchor = "E2:O17"121```122123---124125# Requirements for Outputs126127## All Excel files128129### Professional Font130- Use a consistent, professional font (e.g., Arial, Times New Roman) for all deliverables unless otherwise instructed by the user131132### Zero Formula Errors133- Every Excel model MUST be delivered with ZERO formula errors (#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?)134135### Preserve Existing Templates (when updating templates)136- Study and EXACTLY match existing format, style, and conventions when modifying files137- Never impose standardized formatting on files with established patterns138- Existing template conventions ALWAYS override these guidelines139140## Financial models141142### Color Coding Standards143Unless otherwise stated by the user or existing template144145#### Industry-Standard Color Conventions146- **Blue text (RGB: 0,0,255)**: Hardcoded inputs, and numbers users will change for scenarios147- **Black text (RGB: 0,0,0)**: ALL formulas and calculations148- **Green text (RGB: 0,128,0)**: Links pulling from other worksheets within same workbook149- **Red text (RGB: 255,0,0)**: External links to other files150- **Yellow background (RGB: 255,255,0)**: Key assumptions needing attention or cells that need to be updated151152### Number Formatting Standards153154#### Required Format Rules155- **Years**: Format as text strings (e.g., "2024" not "2,024")156- **Currency**: Use $#,##0 format; ALWAYS specify units in headers ("Revenue ($mm)")157- **Zeros**: Use number formatting to make all zeros "-", including percentages (e.g., "$#,##0;($#,##0);-")158- **Percentages**: Default to 0.0% format (one decimal)159- **Multiples**: Format as 0.0x for valuation multiples (EV/EBITDA, P/E)160- **Negative numbers**: Use parentheses (123) not minus -123161162### Formula Construction Rules163164#### Assumptions Placement165- Place ALL assumptions (growth rates, margins, multiples, etc.) in separate assumption cells166- Use cell references instead of hardcoded values in formulas167- Example: Use =B5*(1+$B$6) instead of =B5*1.05168169#### Formula Error Prevention170- Verify all cell references are correct171- Check for off-by-one errors in ranges172- Ensure consistent formulas across all projection periods173- Test with edge cases (zero values, negative numbers)174- Verify no unintended circular references175176## Reading and analyzing data177178Read .xlsx files by downloading from the given S3 path and using tools in `code_interpreter`.179180### Data analysis with pandas181182```python183import boto3184import pandas as pd185186s3 = boto3.client('s3')187s3.download_file(bucket, key, 'spreadsheet.xlsx')188189df = pd.read_excel('spreadsheet.xlsx') # Default: first sheet190all_sheets = pd.read_excel('spreadsheet.xlsx', sheet_name=None) # All sheets as dict191192df.head() # Preview data193df.info() # Column info194df.describe() # Statistics195```196197## Excel File Workflows198199## CRITICAL: Use Formulas, Not Hardcoded Values200201**Always use Excel formulas instead of calculating values in Python and hardcoding them.** This ensures the spreadsheet remains dynamic and updateable.202203### ❌ WRONG - Hardcoding Calculated Values204```python205total = df['Sales'].sum()206sheet['B10'] = total # Hardcodes 5000207208growth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue']209sheet['C5'] = growth # Hardcodes 0.15210```211212### ✅ CORRECT - Using Excel Formulas213```python214sheet['B10'] = '=SUM(B2:B9)'215sheet['C5'] = '=(C4-C2)/C2'216```217218Formulas are stored as strings by openpyxl and recalculated automatically when the user opens the file in Excel or LibreOffice Calc.219220## Common Workflow2211. **Choose tool**: pandas for data, openpyxl for formulas/formatting2222. **Create/Load**: Create new workbook or load existing file2233. **Modify**: Add/edit data, formulas, and formatting2244. **Save**: Write to file2255. **Upload**: Upload to S3226227### Creating new Excel files228229```python230from openpyxl import Workbook231from openpyxl.styles import Font, PatternFill, Alignment232import boto3233234wb = Workbook()235sheet = wb.active236237sheet['A1'] = 'Hello'238sheet['B1'] = 'World'239sheet.append(['Row', 'of', 'data'])240241sheet['B2'] = '=SUM(A1:A10)'242243sheet['A1'].font = Font(bold=True, color='FF0000')244sheet['A1'].fill = PatternFill('solid', start_color='FFFF00')245sheet['A1'].alignment = Alignment(horizontal='center')246247sheet.column_dimensions['A'].width = 20248249wb.save('./output.xlsx')250251# Upload to S3252s3 = boto3.client('s3')253with open('./output.xlsx', 'rb') as f:254 s3.upload_fileobj(255 f, BUCKET, KEY,256 ExtraArgs={'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}257 )258```259260### Editing existing Excel files261262```python263from openpyxl import load_workbook264import boto3265266# Download from S3267s3 = boto3.client('s3')268s3.download_file(bucket, key, 'existing.xlsx')269270wb = load_workbook('existing.xlsx')271sheet = wb.active # or wb['SheetName'] for specific sheet272273for sheet_name in wb.sheetnames:274 sheet = wb[sheet_name]275276sheet['A1'] = 'New Value'277sheet.insert_rows(2)278sheet.delete_cols(3)279280new_sheet = wb.create_sheet('NewSheet')281new_sheet['A1'] = 'Data'282283wb.save('./modified.xlsx')284285# Upload to S3286with open('./modified.xlsx', 'rb') as f:287 s3.upload_fileobj(288 f, BUCKET, KEY,289 ExtraArgs={'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}290 )291```292293## Best Practices294295### Library Selection296- **pandas**: Best for data analysis, bulk operations, and simple data export297- **openpyxl**: Best for complex formatting, formulas, and Excel-specific features298299### Working with openpyxl300- Cell indices are 1-based (row=1, column=1 refers to cell A1)301- Use `data_only=True` to read cached values from existing files: `load_workbook('file.xlsx', data_only=True)`302- **Note**: openpyxl-generated files do not have cached formula values — formulas recalculate when opened in Excel/LibreOffice Calc303- For large files: Use `read_only=True` for reading or `write_only=True` for writing304305### Working with pandas306- Specify data types to avoid inference issues: `pd.read_excel('file.xlsx', dtype={'id': str})`307- For large files, read specific columns: `pd.read_excel('file.xlsx', usecols=['A', 'C', 'E'])`308- Handle dates properly: `pd.read_excel('file.xlsx', parse_dates=['date_column'])`309310## Code Style Guidelines311**IMPORTANT**: When generating Python code for Excel operations:312- Write minimal, concise Python code without unnecessary comments313- Avoid verbose variable names and redundant operations314- Avoid unnecessary print statements315316**For Excel files themselves**:317- Document data sources for hardcoded values318- Include notes for key calculations and model sections319320---321322## Dependencies323324`openpyxl`, `pandas`, `boto3`, `numpy`, `Pillow`, `matplotlib` are pre-installed in the Code Interpreter sandbox. Do NOT call `!pip install` — import directly.