Data Report
ZJU-REAL/Easel
把 CSV、Excel 或 JSON 数据生成包含 KPI、图表和洞察的完整可视化报告页。当用户说“数据报告、CSV/Excel 转报告、做 KPI 看板、生成可视化报告页”时使用。单张图表用 chart-visualization;信息图或 GIF 动画图表用 infographic。
A skill your agent uses to build a multi-element Excel dashboard - Dashboard sheet on open, multiple formula-driven KPI cards, multiple charts, sparklines, and conditional formatting - from CSV or…
$ npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install FerroxLabs/wayland officecli-data-dashboard --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .claude/skills && cp -r skills-src/src/process/resources/skills/officecli-data-dashboard .claude/skills/officecli-data-dashboard && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "officecli-data-dashboard" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills/officecli-data-dashboard into .claude/skills/officecli-data-dashboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "officecli-data-dashboard", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills/officecli-data-dashboardType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install FerroxLabs/wayland officecli-data-dashboard --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .agents/skills && cp -r skills-src/src/process/resources/skills/officecli-data-dashboard .agents/skills/officecli-data-dashboard && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "officecli-data-dashboard" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills/officecli-data-dashboard into .agents/skills/officecli-data-dashboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "officecli-data-dashboard", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install FerroxLabs/wayland officecli-data-dashboard --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/src/process/resources/skills/officecli-data-dashboard .cursor/skills/officecli-data-dashboard && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "officecli-data-dashboard" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills/officecli-data-dashboard into .cursor/skills/officecli-data-dashboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "officecli-data-dashboard", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/FerroxLabs/wayland.git --path src/process/resources/skills/officecli-data-dashboard--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install FerroxLabs/wayland officecli-data-dashboard --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/src/process/resources/skills/officecli-data-dashboard .gemini/skills/officecli-data-dashboard && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "officecli-data-dashboard" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills/officecli-data-dashboard into .gemini/skills/officecli-data-dashboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "officecli-data-dashboard", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install FerroxLabs/wayland officecli-data-dashboardInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .github/skills && cp -r skills-src/src/process/resources/skills/officecli-data-dashboard .github/skills/officecli-data-dashboard && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "officecli-data-dashboard" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills/officecli-data-dashboard into .github/skills/officecli-data-dashboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "officecli-data-dashboard", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install FerroxLabs/wayland officecli-data-dashboard --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/FerroxLabs/wayland.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/src/process/resources/skills/officecli-data-dashboard .opencode/skills/officecli-data-dashboard && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "officecli-data-dashboard" agent skill from https://github.com/FerroxLabs/wayland/tree/main/src/process/resources/skills/officecli-data-dashboard into .opencode/skills/officecli-data-dashboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "officecli-data-dashboard", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
officecli-data-dashboardA skill your agent uses to build a multi-element Excel dashboard - Dashboard sheet on open, multiple formula-driven KPI cards, multiple charts, sparklines, and conditional formatting - from CSV or…
Officecli Data Dashboard is an agent skill from FerroxLabs/wayland. Use this skill to build a multi-element Excel dashboard - Dashboard sheet on open, multiple formula-driven KPI cards, multiple charts, sparklines, and conditional formatting - from CSV or tabular input. Trigger on: 'dashboard', 'KPI dashboard', 'analytics dashboard', 'executive dashboard', 'metrics dashboard', 'CSV to dashboard', 'data visualization'. Output is a single .xlsx. Scene-layer on officecli-xlsx: inherits every xlsx hard rule. DO NOT invoke for: a single budget tracker / one-sheet CSV-with-formatting…
Its SKILL.md is about 9.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Documents & Office, covering Excel spreadsheets, Financial modeling and OKRs and executive reporting. It works with Microsoft Excel. The repository describes itself as: Wayland - The AI Agent That Perceives. Reasons. Acts. Evolves. The licence is AGPL-3.0.
5 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 4c030c7. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
jqFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
schemas.openxmlformats.orgFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Officecli Data Dashboard loads about 9.2k tokens when it runs. Until then it costs about 169 tokens; SKILL.md has 2,647 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from FerroxLabs/wayland at commit 4c030c7, republished under its AGPL-3.0 licence (© FerroxLabs). 2,647 words, ~9,224 tokens.
.claude/skills/officecli-data-dashboard/SKILL.md (or your agent's skills folder).A dashboard is not "a spreadsheet with charts". It is a composition: one Dashboard sheet the user lands on with formula-driven KPI cards, cell-range-linked charts, sparklines, and semantic conditional formatting. Everything else (raw data, aggregations) is upstream infrastructure the user should never need to open. This skill teaches the composition pattern. Everything about the xlsx engine - cells, formulas, batch JSON, shell quoting, validate, HTML preview - comes from officecli-xlsx and is not re-taught here.
Wayland Desktop supplies a checksum-pinned native officecli runtime. Do not install, update, download, or replace it from this skill. Native authoring requires the exact verified 1.0.136 version. If officecli --version or the required officecli --help surface fails, stop and use Wayland's reinstall/update recovery path; never bootstrap mutable code or silently switch to hosted-credit generation.
When a prop name, enum value, or alias is uncertain, consult help before guessing.
officecli help xlsx # element list
officecli help xlsx chart # full schema for charts
officecli help xlsx sparkline # sparklines
officecli help xlsx conditionalformatting # all CF rule typesHelp reflects the installed CLI version. When this skill and help disagree, help wins. DeferredAddKeys (preset, referenceline, trendline, axisNumFmt, holesize, combosplit) work on add only - see Reference.
This skill inherits every xlsx hard rule from officecli-xlsx - shell quoting, zero formula errors, visual delivery floor, batch JSON shape ({"command":"set"|"add","path":...,"props":{...}} - key is command, NOT action), batch JSON dotted-name rule, chart data-feed forms, batch+resident limits, validate discipline. Read officecli-xlsx first; honour those rules, do not re-teach them here.
Reverse handoff - do NOT use this skill when:
officecli-xlsx.officecli-financial-model.officecli-xlsx.This skill only accepts: "a Dashboard sheet the user opens first, multiple KPI cards, multiple charts, some CF / sparklines".
→ see officecli-xlsx §Shell & Execution Discipline for the baseline (quoting, heredoc for !, incremental execution).
Two increments specific to dashboards:
add commands exceed 180 chars. Always split across lines with trailing \; never pack a chart command onto a single line. The longer the command, the higher the chance a shell-escape bug hides inside it.query --json | jq length, never raw-get | grep -c. Example: officecli query "$FILE" chart --json | jq '.data.results | length' for "how many charts do I have?".Five non-negotiable principles. If any one is violated the output is not a dashboard, it is a spreadsheet that happens to have a chart.
Formula-driven KPIs. Every KPI value on the Dashboard sheet is a formula - SUM, AVERAGE, IFERROR((...-...)/...,0), whatever - referring to cells on the Data / Summary sheet. Never hardcode a computed number. When the underlying data changes tomorrow, KPIs update on open.
Cell-range references for charts. Every chart series reads from a cell range: series1.values="Sheet1!B2:B13". Inline data="Revenue:100,200,300" is for a 5-minute demo, not a delivered dashboard. The one exception: data requires an aggregation Excel cannot express (rare) - document the exception in a comment cell.
Dashboard-first architecture. KPI label cells, KPI value cells, charts, sparklines all live on the Dashboard sheet - the single sheet a user lands on. Raw imports and SUMIFS rollups live on Data / Summary sheets, upstream of the Dashboard. The user should never need to switch tabs to find the answer.
Visible cells only for chart sources. LibreOffice does not evaluate formulas in hidden columns or hidden sheets at render time. A chart whose series1.values points at a hidden-column SUMIFS renders blank. Pattern: aggregate into a visible Summary sheet, point charts at Summary cells, hide only helper columns that are not chart sources.
Data-size-aware complexity. A 10-row dataset does not get 5 KPIs and 4 charts. A 200-row dataset does not get 1 KPI and 1 chart. Scale up the composition with the input (table in §Design Ideas). Overbuilding is as wrong as underbuilding.
All officecli-xlsx requirements apply (→ see officecli-xlsx §Requirements for Outputs). Dashboards add these:
officecli query "$FILE" sheet BEFORE filling activeTab="N". Never guess the index.calc.fullCalcOnLoad=true. Set via officecli set "$FILE" / --prop calc.fullCalcOnLoad=true. Do NOT raw-set <calcPr> - it produces duplicate elements that fail validate.fullCalcOnLoad=true schedules runtime recalc only; it does NOT refresh build-time cachedValue. After set B=100 → set E==B+D → fix B=150, E is stale until you re-issue E's formula (or close/reopen). Stale cache ships "Net Change = 0" to the board."Series1" in a legend is unfinished work.officecli query "$FILE" 'Dashboard!:has(formula)' --json | jq '.data.results | length' should equal your planned KPI count.fill=1F3864 + font.color=FFFFFF + font.bold=true).width ≈ ceil((visible_chars + 2) × 1.3). A KPI holding ¥1,958,414,250 (14 visible chars with currency + commas) needs width ≥ 28; a 4-digit KPI still needs width ≥ 22 as the floor. Hardcoding 22 for a 10+ digit KPI is how ### ships to the user./Dashboard/row[N] height=22 (or 24 when paired with a 24pt KPI value cell in the same row)._xlnm.Print_Area scoped to Dashboard + hide non-Dashboard sheets + add <pageSetup fitToPage/>. Without all three, the print pipeline emits every sheet and Dashboard lands on page 2+. See §Print-ready delivery for the exact commands.Minimal viable dashboard: 12-month revenue CSV → 4 KPIs + 1 line chart + activeTab + fullCalcOnLoad. Adapt the numbers, don't copy-paste blind. Broken into phases so a single failed phase is obvious.
Phase 1 - Data sheet: create, import, format.
FILE=my_dashboard.xlsx
officecli create "$FILE"
officecli import "$FILE" /Sheet1 --file sales.csv --header
officecli set "$FILE" '/Sheet1/col[A]' --prop width=12
officecli set "$FILE" '/Sheet1/col[B]' --prop width=15
officecli set "$FILE" '/Sheet1/B2:B13' --prop numFmt='$#,##0'
officecli set "$FILE" '/Sheet1/A1:B1' --prop fill=1F3864 --prop font.color=FFFFFF --prop font.bold=truePhase 2 - Dashboard sheet + one KPI card.
officecli add "$FILE" / --type sheet --prop name=Dashboard
officecli set "$FILE" '/Dashboard/col[A]' --prop width=22
officecli set "$FILE" '/Dashboard/col[B]' --prop width=12
officecli set "$FILE" /Dashboard/A1 --prop value="Total Revenue" --prop font.size=9 --prop font.color=666666 --prop bold=true
officecli set "$FILE" /Dashboard/A2 --prop 'formula==SUM(Sheet1!B2:B13)' --prop numFmt='$#,##0' --prop font.size=24 --prop bold=true --prop font.color=2E7D32Phase 3 - Sparkline + chart.
officecli add "$FILE" /Dashboard --type sparkline --prop cell=B2 --prop range='Sheet1!B2:B13' --prop type=line --prop color=4472C4 --prop highPoint=true --prop highMarkerColor=FF0000
officecli add "$FILE" /Dashboard --type chart \
--prop chartType=line \
--prop title="Revenue Trend" \
--prop series1.name="Revenue" \
--prop series1.values='Sheet1!B2:B13' \
--prop series1.categories='Sheet1!A2:A13' \
--prop preset=dashboard --prop axisNumFmt='$#,##0' \
--prop x=0 --prop y=5 --prop width=10 --prop height=15Phase 4 - fullCalcOnLoad → activeTab (LAST) → close → validate.
officecli set "$FILE" / --prop calc.fullCalcOnLoad=true
# Resolve Dashboard's 0-based index from the actual sheet list - never hardcode.
DASH_IDX=$(officecli query "$FILE" sheet --json \
| jq '[.data.results[].path] | index("/Dashboard")')
officecli raw-set "$FILE" /workbook --xpath "//x:sheets" --action insertbefore \
--xml "<bookViews xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"><workbookView activeTab=\"$DASH_IDX\" /></bookViews>"
officecli close "$FILE"
officecli validate "$FILE"Verified end-to-end on a 12-row revenue CSV: validate reports no errors, Dashboard opens first, Dashboard/A2.cachedValue resolves (2,075,000 for the test data), chart renders with values linked.
Options, not templates. The user's data and audience drive the choices.
Pattern 1 - executive summary (board packs): KPI strip A1:H4, charts stack from row 6.
┌ KPI1 │ KPI2 │ KPI3 │ KPI4 ┐ rows 1-4
├──────┴──────┴──────┴──────┤
│ Chart 1 (wide) │ rows 6-18
├───────────────┬───────────┤
│ Chart 2 │ Chart 3 │ rows 20-32Pattern 2 - ops console (live ops): KPIs down A:B, charts fill C:L.
│ KPI1 │ │
│ KPI2 │ Chart 1 │ rows 1-12
│ KPI3 │ │
│ KPI4 ├───────────────────┤
│ KPI5 │ Chart 2 │ rows 14-26Pattern 3 - scorecard (≥ 6 KPIs, no dominant chart): grid of 2×3 cards (label / value / sparkline).
│ KPI1 │ KPI2 │ KPI3 │ rows 1-4
│ KPI4 │ KPI5 │ KPI6 │ rows 5-8| Rows | KPIs | Charts | Sparklines | CF rules | Preset |
|---|---|---|---|---|---|
| < 10 | 1–2 | 1 | skip | 0–1 | minimal |
| 10–50 | 2–3 | 2 | only if sequential time-series | 1–2 | dashboard |
| 50–200 | 3–5 | 2–3 | only if sequential time-series | 2–3 | dashboard |
| 200+ | 3–5 | 3 | only if sequential time-series | 3–4 | dashboard |
| Data pattern | Chart type | Notes |
|---|---|---|
| Trend over time, one series | line | Add trendline=linear to show direction on noisy series |
| Trend over time, multiple components | line (multi-series) or columnStacked | Stacked when components sum to a meaningful total |
| Comparison across categories in time order | column | Not bar - horizontal bars break left-to-right time reading |
| Part-of-whole breakdown | doughnut | Prefer over pie: chartType=pie has a known LibreOffice blank-render regression |
| Budget vs actual | combo with combosplit=1 | First series as bars, rest as lines |
| Correlation | scatter | Uses series1.xValues, NOT series1.categories |
--prop preset=<name> on every chart. Options: minimal, dashboard, corporate, magazine, colorful, monochrome, dark. Pick one and stay consistent across all charts on a single Dashboard - mixing presets reads as accidental.
Four CF rule types; each uses --type <shorthand> at add time:
| Intent | --type | Typical props |
|---|---|---|
| Magnitude bar (sales, spend) | databar | sqref=B2:B13 color=4472C4 min=0 max=<plausible> - always set explicit min/max; defaults emit invalid XML |
| Heat map (rates, growth) | colorscale | sqref=D2:D13 mincolor=FFCDD2 midcolor=FFFFFF maxcolor=C8E6C9 |
| Status indicator | iconset | sqref=E2:E13 iconset=3Arrows - see help for the full enum |
| Custom business rule | formulacf | sqref=B2:B13 'formula=$B2>=100000' fill=C8E6C9 font.color=2E7D32 - NEVER font.bold (schema rejects <b>) |
Semantic colors to stay consistent within a dashboard:
C8E6C9, font 2E7D32FFCDD2, font C62828F5F5F5, font 666666A card is a label cell + a value cell. The label is small gray (font.size=9, font.color=666666, bold); the value is large bold (font.size=24, bold=true, numFmt, font.color signals tone). One row of light fill (e.g. F0F4FF) across the card area gives the "card" read without building merged-cell scaffolds. Value column width must be sized to the largest cachedValue - never narrower than 22, often 26–32 for 8+ digit currency (see Requirements).
At the dashboard preset's default title font, the chart plot-box width (in column units) must stay ahead of the title string, or the title clips mid-word. Rule of thumb: chart.width ≥ ceil(title.length × 0.18). A 35-character title ("Department: Year-End Headcount vs Attrition Rate") needs width ≥ 7; be safer and use 10–12. If the anchor cannot be widened, shorten the title to ≤ 25 characters - clipped titles in a board-ready deliverable are indefensible.
officecli get chart[N] does not expose numeric width on 1.0.63 - it returns .data.format.anchor (e.g. "A6:K21"). Derive column span from letters (A→K = 10 cols) for Gate 2.
Triggers: ask contains "print" / "one-pager" / "board" / "investor". Four artefacts on the Dashboard sheet; non-Dashboard sheets hidden so the print pipeline emits one page only.
# 1. Print_Area scoped to Dashboard (xlnm convention).
officecli add "$FILE" / --type namedrange --prop name=_xlnm.Print_Area --prop scope=Dashboard --prop 'refersTo=Dashboard!$A$1:$H$36'
# 2. fit-to-page on Dashboard.
officecli raw-set "$FILE" /Dashboard --xpath "//x:worksheet" --action prepend --xml '<sheetPr xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><pageSetUpPr fitToPage="1"/></sheetPr>'
# 3. Landscape page setup.
officecli raw-set "$FILE" /Dashboard --xpath "//x:sheetData" --action insertafter --xml '<pageSetup orientation="landscape" paperSize="9" fitToWidth="1" fitToHeight="1"/>'
# 4. Hide non-Dashboard sheets - Print_Area scope alone does NOT stop the print pipeline from emitting every visible sheet.
for S in Sheet1 Summary; do
officecli raw-set "$FILE" /workbook --xpath "//x:sheet[@name='$S']" --action setattr --xml "state=hidden" || true
doneDelete any Print_Area set on Data / Summary sheets - conflicting scopes emit multi-page output.
Assume there are problems. Your job is to find them. A chart that was rendered does not mean a chart that was meaningful. "validate pass" is not delivery; "the Dashboard sheet reads like someone who knows the business made it" is delivery.
Inherit the xlsx baseline (view issues, formula error queries, validate, HTML preview scan): → see officecli-xlsx §QA minimum cycle.
Then run the dashboard-specific Delivery Gates. Each gate uses COUNT-then-if pattern with a .data.* wrapper - never chain && echo OK || echo FAIL.
Gate 1 - KPI formula coverage. Every planned KPI cell must carry a formula. Adjust -lt 2 to your plan (4 KPIs → -lt 4).
KPI_FORMULAS=$(officecli query "$FILE" 'Dashboard!:has(formula)' --json | jq '.data.results | length')
[ "$KPI_FORMULAS" -lt 2 ] && { echo "REJECT Gate 1: $KPI_FORMULAS formula cells on Dashboard"; exit 1; }Gate 2 - Chart count matches plan, every chart has data + plausible title width.
CHART_COUNT=$(officecli query "$FILE" chart --json | jq '.data.results | length')
[ "$CHART_COUNT" -lt 1 ] && { echo "REJECT Gate 2: zero charts"; exit 1; }
col_num () { local c=$1 n=0; for ((k=0;k<${#c};k++)); do n=$((n*26+$(printf '%d' "'${c:$k:1}")-64)); done; echo "$n"; }
for i in $(seq 1 "$CHART_COUNT"); do
JSON=$(officecli get "$FILE" "/Dashboard/chart[$i]" --json)
SC=$(echo "$JSON" | jq -r '.data.format.seriesCount // 0')
TITLE=$(echo "$JSON" | jq -r '.data.format.title // ""')
ANCHOR=$(echo "$JSON" | jq -r '.data.format.anchor // ""')
[ "$SC" = "0" ] || [ -z "$TITLE" ] && { echo "REJECT Gate 2: chart[$i] seriesCount=$SC title='$TITLE'"; exit 1; }
[ -z "$ANCHOR" ] && continue
LCOL=$(echo "${ANCHOR%%:*}" | sed 's/[0-9]*$//'); RCOL=$(echo "${ANCHOR##*:}" | sed 's/[0-9]*$//')
SPAN=$(( $(col_num "$RCOL") - $(col_num "$LCOL") + 1 ))
MIN=$(( (${#TITLE} * 18 + 99) / 100 ))
[ "$SPAN" -lt "$MIN" ] && { echo "REJECT Gate 2: chart[$i] title=${#TITLE} chars needs width ≥ $MIN, anchor spans $SPAN"; exit 1; }
doneNarrower titles at preset minimal / magazine may clip earlier than the 0.18 factor - spot-check.
Gate 3 - Chart series names populated (no "Series1" in legend).
for i in $(seq 1 "$CHART_COUNT"); do
BAD=$(officecli get "$FILE" "/Dashboard/chart[$i]" --json | jq '[.data.children[]? | select(.type == "series") | select((.format.name // "") | test("^Series[0-9]+$"; "i"))] | length')
[ "$BAD" -gt 0 ] && { echo "REJECT Gate 3: chart[$i] has $BAD auto-named series"; exit 1; }
doneGate 4 - CF rules on Data sheet (10+ rows).
CF_COUNT=$(officecli query "$FILE" conditionalformatting --json | jq '.data.results | length')
[ "$CF_COUNT" -lt 1 ] && { echo "REJECT Gate 4: zero CF rules on 10+ row data sheet"; exit 1; }Note: query conditionalformatting is the canonical element name; query cf returns 0 (not an alias).
Gate 5 - activeTab and fullCalcOnLoad set. Compare against real Dashboard index (Dashboard-at-index-0 is a true pass).
DASH_IDX=$(officecli query "$FILE" sheet --json | jq '[.data.results[].path] | index("/Dashboard")')
ACTIVE=$(officecli get "$FILE" /workbook --json | jq '.data.format.activeTab // -1')
FULLCALC=$(officecli get "$FILE" /workbook --json | jq -r '.data.format["calc.fullCalcOnLoad"] // false')
[ "$ACTIVE" != "$DASH_IDX" ] && { echo "REJECT Gate 5: activeTab=$ACTIVE Dashboard=$DASH_IDX"; exit 1; }
[ "$FULLCALC" != "true" ] && { echo "REJECT Gate 5: calc.fullCalcOnLoad=$FULLCALC - stale caches will ship"; exit 1; }Gate 6 - Placeholder sweep. No build-time tokens in rendered output.
LEAKS=$(officecli view "$FILE" text 2>/dev/null | grep -niE '\{\{|\$fy\$|<TODO>|xxxx|TBD' | wc -l | tr -d ' ')
[ "$LEAKS" -gt 0 ] && { echo "REJECT Gate 6: $LEAKS placeholder tokens"; exit 1; }Gate 7 - Visual delivery floor (ported from xlsx). Run officecli view "$FILE" html and Read the returned HTML path. Confirm:
### in any Dashboard or Data cell (columns too narrow).$fy$24, {var}, <TODO>, xxxx).If view html is blocked (renderer conflict, headless, port busy), Gate 7 is still mandatory - run ALL fallback checks:
# a) Token / ### sweep.
officecli view "$FILE" text 2>/dev/null | grep -nE '###|\{\{|<TODO>|\$fy\$|xxxx' && { echo "REJECT Gate 7: tokens or ### present"; exit 1; }
# b) Per-KPI: cachedValue length × coef must fit col width. coef=0.55 fit-to-page, 0.85 otherwise.
for CELL in A2 C2 E2 G2; do
CV=$(officecli get "$FILE" "/Dashboard/$CELL" --json | jq -r '.data.format.cachedValue // .data.text // ""')
W=$(officecli get "$FILE" "/Dashboard/col[${CELL%%[0-9]*}]" --json | jq -r '.data.format.width // 0')
CAP=$(echo "$W * 0.55" | bc -l | awk '{print int($1)}')
[ "${#CV}" -gt "$CAP" ] && { echo "REJECT Gate 7: $CELL '$CV' (${#CV} chars) > cap $CAP"; exit 1; }
done
# c) Rerun Gate 2 title × 0.18 ≤ anchor span. d) Log which fallback was used and why.Gate 7 must NEVER be skipped - skipping ships ### to the user.
If scene keywords include print / one-pager / board / investor, extend Gate 7 with a structural print-scope check:
if echo "$USER_REQ" | grep -qiE 'print|one-pager|investor|board'; then
# Every non-Dashboard sheet must be hidden or veryHidden.
LEAKING=$(officecli query "$FILE" 'sheet' --json | jq -r '.data.results[] | select(.name != "Dashboard" and (.state // "visible") == "visible") | .name')
[ -n "$LEAKING" ] && { echo "REJECT Gate 7 print-scope: visible non-Dashboard sheet(s): $LEAKING - hide before delivery"; exit 1; }
# Dashboard must carry an explicit Print_Area named range.
PA=$(officecli query "$FILE" 'namedrange[name="_xlnm.Print_Area"]' --json | jq '.data.results | length')
[ "$PA" -ge 1 ] || { echo "REJECT Gate 7 print-scope: no _xlnm.Print_Area set"; exit 1; }
fiThe user opens the file in their target viewer (Office / WPS / Numbers) for the final print preview - the skill does not render export artefacts.
Gate 8 - Formula sanity (cachedValue real, not stale/error). fullCalcOnLoad=true refreshes at runtime, NOT build-time cache - so every formula cell must carry a non-empty, non-zero, non-error cachedValue now.
for CELL in A2 C2 E2 G2; do
JSON=$(officecli get "$FILE" "/Dashboard/$CELL" --json)
[ -z "$(echo "$JSON" | jq -r '.data.format.formula // ""')" ] && continue
CV=$(echo "$JSON" | jq -r '.data.format.cachedValue // ""')
case "$CV" in
"" | "0" | "#DIV/0!" | "#REF!" | "#N/A" | "#VALUE!" | "#NAME?" | "null")
echo "REJECT Gate 8: $CELL cachedValue='$CV' - re-issue formula or close+reopen"; exit 1 ;;
esac
doneIf a KPI is genuinely zero (e.g. "terminations this quarter" = 0), whitelist it in the loop and document - default assumption is "zero is broken".
If anything fails, fix at source, re-run the full cycle.
Scatter's series1.xValues is not exposed in get --json (series values="") - use chart-level seriesCount. LibreOffice chart color drift / pie-slice collapse / checkbox double-box are viewer artifacts - spot-check in Office / WPS / Numbers first.
--type at add: chart, sparkline, databar, colorscale, iconset, formulacf. CF rules map to help xlsx conditionalformatting; path suffix /Sheet/cf[N].officecli help xlsx chart / sparkline / conditionalformatting. This skill does not mirror them.set): preset, trendline, referenceline, axisNumFmt, combosplit, holesize. See D-1.calc.fullCalcOnLoad=true via high-level set → raw-set activeTab LAST (after all sheets exist).| # | Issue | Mitigation |
|---|---|---|
| D-1 | preset, referenceline, trendline, axisNumFmt are DeferredAddKeys - work on add only, silently ignored on set | Include them at add time. Cannot apply after the fact - remove + re-add. |
| D-2 | referenceline format is value:color:label:dash (color BEFORE label). "0:Break-Even:FF0000:dash" fails Invalid color value. | Order is value, color, label, dash. |
| D-3 | Scatter charts use series1.xValues, not series1.categories. <cat> inside <scatterChart> is schema-invalid. | --prop series1.xValues="Sheet1!A2:A13" |
| D-4 | formulacf rejects font.bold (dxf/font schema disallows <b>). | Use fill + font.color only; bold is not available via CF. |
| D-5 | Dashboard column widths default to 8.43 - KPI values at 24pt bold show ### | Size by cachedValue bracket: 4–6 digits → 22–24; 7–9 digits (million) → 26–30; 10+ digits (billion) → 32–36; 10-digit + currency symbol + fit-to-page landscape → 40–44. Formula ceil((visible_chars+2)*1.3) is a starting point; always verify via Gate 7 fallback b). Sparkline columns: 12. |
| D-6 | raw-set activeTab must be the LAST mutation. Inserting before all sheets exist shifts indices. | Finish all sheets / charts / CF / sparklines / tabColors, then raw-set. |
| D-7 | calc.fullCalcOnLoad via raw-set creates duplicate <calcPr> → validate fails | Use officecli set "$FILE" / --prop calc.fullCalcOnLoad=true. |
| D-8 | LibreOffice does not evaluate hidden-column formulas at render → charts referencing hidden cells render blank | Aggregate into a visible Summary sheet, chart reads from Summary. Hide only columns that are not chart sources. |
| D-9 | chartType=pie blank-renders in LibreOffice (v1.0.x) | Use doughnut as the safe substitute for part-of-whole breakdowns. |
| D-10 | SUMIFS / AVERAGEIFS with date criteria fails silently if the criterion is a string | Wrap with DATE() or DATEVALUE(): =SUMIFS(B2:B13,A2:A13,DATE(2025,1,5)). |
| D-11 | Summary sheet percentage formulas display as raw decimals (0.098) without numFmt | Set numFmt="0.0%" at the same set call as the formula. |
| D-12 | import --header sets freeze + AutoFilter but does NOT set column widths; numFmt on a col[] path is rejected | Set widths on col[]; set numFmt on the cell range (A2:A13), not the column. |
| D-13 | Sparkline highpoint is a bool (highlight on/off), not a color. --prop highpoint=FF0000 errors Invalid boolean value | --prop highPoint=true --prop highMarkerColor=FF0000. Same pattern for lowPoint / firstPoint / lastPoint and their *MarkerColor. |
| D-14 | Sparkline cross-sectional data is meaningless (a region or department has no ordering) | Skip sparklines unless rows are a sequential time-series (dates, months, quarters). |
| D-15 | 1.0.63+ rejects empty chart add (Chart requires data) at the CLI layer - legacy skills that relied on silent accept will fail here | Always provide series1.values= / dataRange= / inline data= at chart add time. Treat Gate 2 seriesCount check as a belt-and-braces verification. |
| D-16 | fullCalcOnLoad=true guarantees a runtime recalc when the end user opens the file; it does NOT refresh the build-time cachedValue in XML. Build sequence set B=100 → set E==B+D → fix B=150 leaves E.cachedValue stale (board sees "Net Change = 0"). | After all upstream edits are final, re-issue every downstream formula (officecli set "$FILE" /Sheet/E2 --prop formula==B2+D2) OR close + re-open the file. Gate 8 verifies. |
| D-17 | 1.0.63 built-in calc engine does NOT evaluate SUMPRODUCT with array-predicate form SUMPRODUCT((A2:A97=X)*C2:C97*D2:D97) - cachedValue stays 0/null, Gate 8 rejects. Runtime Excel / WPS compute fine, but board-delivered XLSX with stale cache still ships 0. | Rewrite as helper column + SUMIF: F2==C2*D2 on source sheet, then =SUMIF(B:B, "Region X", F:F). Or pre-aggregate in Summary sheet and chart from there. |
Cross-sheet ! trap, batch + resident for formulas, labelRotation on axis-by-role, chartType=pareto, validate while resident, data bar without explicit min/max, chart anchor / series immutability after create → see officecli-xlsx §Known Issues.
© FerroxLabs, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in src/process/resources/skills/officecli-data-dashboard of FerroxLabs/wayland.
Open the folder on GitHubat commit 4c030c7
We found 4 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 4 other GitHub owners. This page covers the copy in FerroxLabs/wayland, which our catalogue first saw on October 7, 2026.
Officecli Data Dashboard next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Officecli Data Dashboard this skillFerroxLabs/wayland | 608 | 4 repos | ~9.2k | Automated safety check: Pass | AGPL-3.0 | |
| Data ReportZJU-REAL/Easel | 3.2k | — | ~479 | Automated safety check: Pass | Apache-2.0 | |
| Pie Chart Data AnalysisMichaelYang-lyx/AIDABench | 111 | 1 repos | ~964 | Automated safety check: Pass | None | |
| Data Visualization AnalysisDrchronx/ai-agent-research-starter-kit | 135 | — | ~621 | Automated safety check: Pass | Custom licence | |
| Research Data Auto Analysis PlottingDrchronx/ai-agent-research-starter-kit | 135 | — | ~463 | Automated safety check: Pass | Custom licence | |
| Anti Gambling Tradermars-tw/anti-gambling-trader-tw | 897 | — | ~1.9k | Automated safety check: Pass | MIT |
ZJU-REAL/Easel
把 CSV、Excel 或 JSON 数据生成包含 KPI、图表和洞察的完整可视化报告页。当用户说“数据报告、CSV/Excel 转报告、做 KPI 看板、生成可视化报告页”时使用。单张图表用 chart-visualization;信息图或 GIF 动画图表用 infographic。
MichaelYang-lyx/AIDABench
对多Sheet Excel或CSV数据进行分类汇总统计,自动识别关键字段并生成包含占比、数值及美化饼图的可下载分析报告。
Drchronx/ai-agent-research-starter-kit
对CSV/Excel数据进行全面的统计描述、相关性分析和可视化;当用户需要数据分析、数据探索、统计摘要、特征分布分析或相关性分析时使用
Drchronx/ai-agent-research-starter-kit
Automatically analyze research datasets and generate publication-ready statistical tables, correlation figures, grouped comparison plots, and regression diagnostics.
mars-tw/anti-gambling-trader-tw
分析台股 / 台股ETF / 台指期選擇權 / 美股 / 加密貨幣 / 外匯的交易紀錄 (CSV / JSON / Excel),用統計學判斷使用者的獲利是「可重複的優勢」還是 「運氣 + 倖存者偏差(賭博)」,不適合長期投資會明確勸退。內建反詐工具: 掃描群組對話的詐騙話術(scan-text)、檢驗老師宣稱的績效(guru-check)、…
SenseTime-Copilot/raccoon-dataanalysis-skill
Raccoon (小浣熊) Data Analysis - Remote code interpreter and data visualization service powered by SenseTime.
FerroxLabs/wayland
Install, start, connect, and troubleshoot visualization companion projects for Aion/OpenClaw, with Star-Office-UI as the default recommendation.
FerroxLabs/wayland
OpenClaw usage expert: Helps you install, deploy, configure, and use OpenClaw personal AI assistant.
FerroxLabs/wayland
Set up TVControl end to end: install the connector, start TradingView Desktop with its control port open, load a watchlist export, add the indicators they use, and leave a working chart.
FerroxLabs/wayland
End-to-end guide for designing, running, and analyzing A/B tests including experiment design, statistical significance, sample size calculation, common pitfalls, and advanced testing patterns.
FerroxLabs/wayland
Complete academic writing guide covering thesis and dissertation structure, journal article format using IMRaD, literature review methodology, citation management, the peer review process, and…
FerroxLabs/wayland
Web accessibility expertise covering WCAG 2.2 conformance, audit methodology, ARIA patterns, keyboard navigation, screen reader testing, focus management, form accessibility, and automated vs manual…
Works with
Categories
A skill your agent uses to build a multi-element Excel dashboard - Dashboard sheet on open, multiple formula-driven KPI cards, multiple charts, sparklines, and conditional formatting - from CSV or…. Officecli Data Dashboard is an agent skill from FerroxLabs/wayland. Use this skill to build a multi-element Excel dashboard - Dashboard sheet on open, multiple formula-driven KPI cards, multiple charts, sparklines, and conditional formatting - from CSV or tabular input.
Officecli Data Dashboard fits situations like: build a multi-element Excel dashboard - Dashboard sheet on open; multiple formula-driven KPI cards; multiple charts; conditional formatting - from CSV.
Run `npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a claude-code`. Or copy the skill folder (src/process/resources/skills/officecli-data-dashboard in FerroxLabs/wayland) into .claude/skills/officecli-data-dashboard in your project. Claude Code loads it when a task matches its description.
Run `npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a codex`. Or copy the skill folder (src/process/resources/skills/officecli-data-dashboard in FerroxLabs/wayland) into .agents/skills/officecli-data-dashboard in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add FerroxLabs/wayland --skill officecli-data-dashboard -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/officecli-data-dashboard, .gemini/skills/officecli-data-dashboard, .github/skills/officecli-data-dashboard and .opencode/skills/officecli-data-dashboard in your project.
Going by SKILL.md and its folder, Officecli Data Dashboard needs the command-line tools its instructions call (jq).
SKILL.md names 1 domain. In commands or code: schemas.openxmlformats.org; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Officecli Data Dashboard is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 9.2k tokens (SKILL.md is roughly 37k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Officecli Data Dashboard: Data Report (ZJU-REAL/Easel, 3.2k stars), Pie Chart Data Analysis (MichaelYang-lyx/AIDABench, 111 stars), Data Visualization Analysis (Drchronx/ai-agent-research-starter-kit, 135 stars) and Research Data Auto Analysis Plotting (Drchronx/ai-agent-research-starter-kit, 135 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
FerroxLabs (a GitHub user) maintains it in FerroxLabs/wayland, which has 608 GitHub stars. The repository holds 22 skills in this directory. The repository was last updated on October 6, 2026.
Source: FerroxLabs/wayland on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.