> ## Documentation Index
> Fetch the complete documentation index at: https://docs.profy.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# Excel Spreadsheets

> profy-xlsx — create, edit, and analyse .xlsx: formulas over hardcoded values, zero formula errors, financial model conventions

# Excel Spreadsheets (profy-xlsx)

Create, edit, and analyse spreadsheets. In direct opposition to "let the model compute the number and paste it in", the governing constraint here is that **the deliverable must be a live spreadsheet**: formulas stay in the cells, so changing a source value updates everything downstream.

## Activation

`profy-xlsx` is `user_selectable: false` — **automatically available, nothing to tick**. It does not appear in the plugin panel because it has no decision for you to make.

```json theme={null}
{ "id": "profy-xlsx", "activation": { "user_selectable": false } }
```

Its `contracts` declares only `skills: ["skills/"]` and **no tools**. The expert is not calling some "generate Excel" tool; it runs Python (openpyxl / pandas) via `bash` in the sandbox, and the skill document governs how it does so.

The trigger is that **a spreadsheet file is the primary input or output**: `.xlsx`, `.xlsm`, `.csv`, `.tsv`. If the final deliverable is a Word document, an HTML report, or a standalone script, this path is not taken even when tabular data is involved along the way.

## Quick start

```
Summarise this sales data by month, add a year-over-year growth column, and chart the trend
```

```
This workbook is full of #REF! errors — fix them
```

```
Build a three-year financial model with all assumptions in a separate assumptions block
```

## First principle: formulas, not hardcoded values

This is the most repeated rule in the skill and it is worth understanding why.

<CodeGroup>
  ```python Wrong theme={null}
  # Compute in Python, write the answer in
  total = sum(revenues)
  sheet['D20'] = total              # dead number

  growth = (rev_2025 - rev_2024) / rev_2024
  sheet['E5'] = growth              # dead number
  ```

  ```python Right theme={null}
  # Let Excel compute
  sheet['D20'] = '=SUM(D2:D19)'
  sheet['E5']  = '=(D5-C5)/C5'
  sheet['D21'] = '=AVERAGE(D2:D19)'
  ```
</CodeGroup>

The difference is not which is faster to write; it is **what kind of artifact you hand over**. Hardcoding produces a snapshot of numbers — change one input and everything else is silently wrong, with no indication. Leaving formulas produces a model — it can be used, audited, and reused.

The rule applies to **all** computation: totals, percentages, ratios, differences, without exception.

## Mandatory step: recalculate and validate

A freshly written workbook stores formulas as **text** with empty cached values. Delivered as-is, the recipient opens it to blanks or stale numbers. So one step is non-optional:

```bash theme={null}
python scripts/recalc.py output.xlsx
```

The script recalculates via LibreOffice (sandboxed environments where Unix sockets are restricted are handled automatically by `scripts/office/soffice.py`) and returns JSON:

| Result                 | Meaning                | Next step                                            |
| ---------------------- | ---------------------- | ---------------------------------------------------- |
| `status` normal        | No formula errors      | Ready to deliver                                     |
| `status: errors_found` | Formula errors present | Read `error_summary`, locate, fix, recalculate again |

### The five error types that must be zero

| Error     | Meaning           | Common cause                                              |
| --------- | ----------------- | --------------------------------------------------------- |
| `#REF!`   | Invalid reference | A row or column was deleted, leaving a dangling reference |
| `#DIV/0!` | Division by zero  | The denominator cell is blank or zero                     |
| `#VALUE!` | Wrong type        | Text ended up in an arithmetic operation                  |
| `#NAME?`  | Unknown function  | Misspelled, or a function this version does not have      |
| `#N/A`    | Lookup failed     | VLOOKUP / MATCH found no match                            |

**The delivery bar is zero formula errors**, not "mostly computes".

## Financial model conventions

For financial models the skill applies industry-standard conventions so that anyone who has seen a financial model can read it immediately.

### Colour coding

| Colour      | RGB       | Meaning                                              |
| ----------- | --------- | ---------------------------------------------------- |
| Blue text   | 0,0,255   | Hardcoded inputs; numbers users change for scenarios |
| Black text  | 0,0,0     | All formulas and calculations                        |
| Green text  | 0,128,0   | Links to other worksheets in the same workbook       |
| Red text    | 255,0,0   | External links to other files                        |
| Yellow fill | 255,255,0 | Key assumptions needing attention or updating        |

The point of this palette is that you can tell **at a glance which numbers are safe to edit and which are derived**. Overwriting a black cell breaks the model, and colour is the cheapest possible guard rail against that.

### Number formatting

| Type        | Format              | Note                                                   |
| ----------- | ------------------- | ------------------------------------------------------ |
| Years       | Text strings        | `"2024"`, never `2,024`                                |
| Currency    | `$#,##0`            | Always state units in the header, e.g. `Revenue ($mm)` |
| Zeros       | `$#,##0;($#,##0);-` | Zero renders as `-`, percentages likewise              |
| Percentages | `0.0%`              | One decimal by default                                 |
| Multiples   | `0.0x`              | Valuation multiples such as EV/EBITDA, P/E             |
| Negatives   | `(123)`             | Parentheses, not a minus sign                          |

### Formula construction

* **Centralise assumptions**: growth rates, margins, multiples all live in dedicated assumption cells
* **Reference, do not embed**: write `=B5*(1+$B$6)`, never `=B5*1.05`
* **Keep projection formulas consistent** across all periods, otherwise one year quietly computes differently
* **Document every hardcode** with `Source: [System/Document], [Date], [Specific Reference], [URL]`, e.g. `Source: Company 10-K, FY2024, Page 45, Revenue Note`
* **Check for off-by-one range errors** and unintended circular references before delivering

That last documentation rule is easy to skip and determines whether the model is still trustworthy six months later. An undocumented hardcoded number is an assertion nobody can verify.

## Editing existing files: the template wins

<Warning>
  **An existing file's conventions always override every guideline above.** When modifying someone else's workbook, study its existing format, style, and conventions and **match them exactly**. Do not impose standardised formatting.
</Warning>

The reasoning is concrete: you do not know what downstream depends on that format. A sheet parsed by a downstream script on column position breaks entirely the moment you "helpfully" normalise the column order.

## Tool selection

| Situation                               | Use      |
| --------------------------------------- | -------- |
| Data analysis, cleaning, transformation | pandas   |
| Formulas, formatting, charts            | openpyxl |

The standard workflow is: choose tool → create or load → modify → save → **recalculate** → verify and fix.

## Boundaries and failure modes

* **Recalculation depends on LibreOffice.** It is preinstalled in the sandbox; in a local Desktop environment without it, `recalc.py` fails and formulas keep no cached values.
* **Macros in `.xlsm` are not executed.** File structure can be read and written, but macro logic does not participate in calculation.
* **Charts come from openpyxl and are stylistically limited.** Complex visualisation is better served by the visualization capability producing web charts.
* **Very large sheets hit memory limits.** Beyond a few hundred thousand rows, aggregate with pandas first and write the result, rather than loading everything into openpyxl.

### Troubleshooting

| Symptom                                  | Cause                                                           | Fix                                                             |
| ---------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- |
| Every formula cell is blank on open      | `recalc.py` was never run                                       | Run the recalculation script                                    |
| `status: errors_found` keeps recurring   | Surface errors fixed but the reference structure is still wrong | Work through every entry in `error_summary`, not just the first |
| Years render as `2,024`                  | Year stored as a number                                         | Write years as text                                             |
| Changing source data changes nothing     | The result was hardcoded                                        | Replace dead numbers with formulas, then recalculate            |
| Template styling falls apart after edits | Standard formatting was imposed                                 | Roll back and match the original conventions exactly            |

## Verify your output

1. Open the file and change any input cell — **downstream numbers should move**. If they do not, something is hardcoded.
2. Search the whole workbook for `#`; none of the five error types should appear.
3. For financial models, check the colours again: blue should appear only in the input block, black should cover every calculation.

## Related

<CardGroup cols={2}>
  <Card title="Office documents overview" href="/en/documentation/capabilities/office-documents">
    How the four document capabilities differ and when to use each
  </Card>

  <Card title="Data visualization" href="/en/documentation/plugins/3d-development">
    The alternative path when you need interactive charts
  </Card>
</CardGroup>

<Note>
  Verified 2026-08-11. Sources: `services/agent-runtime/src/plugins/builtin/xlsx/plugin.json`, `skills/SKILL.md`, `skills/scripts/recalc.py`, `skills/scripts/office/soffice.py`.
</Note>
