xlsx
Skill0 starsChanged 11 days agoApache-2.0View on GitHub
Excel .xlsx workbooks and CSVs: create, read, edit. For an invoice or a quote, order or delivery note load that pack first, even as Excel.
- Installs packages
194 other projects use a version of this, 5 of them edited.
Adopted by
Most recently taken up by
- aditya-vermax/skillstheir own version, first seen Nov 8, 2026
- CloudChef/atlasclaw-providerstheir own version, first seen Nov 8, 2026
- holon-run/holontheir own version, first seen Nov 8, 2026
- rvdbreemen/OTGW-firmwaretheir own version, first seen Nov 8, 2026
- BrightGold70/skillstheir own version, first seen Nov 8, 2026
- Liang-MH/skillstheir own version, first seen Nov 8, 2026
Used with
Projects with it also use Video Generation, VLM and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
huang-x-hSkillVideo Generation
Implement AI-powered video generation capabilities using the z-ai-web-dev-sdk. Use this skill when the user needs to generate videos from text prompts or images, create video content programmatically, or build applications that produce video outputs. Supports asynchronous task management with status polling and result retrieval.
Also in 6 projects that use this
huang-x-hSkillVLM
Implement vision-based AI chat capabilities using the z-ai-web-dev-sdk. Use this skill when the user needs to analyze images, describe visual content, or create applications that combine image understanding with conversational AI. Supports image URLs and base64 encoded images for multimodal interactions.
Also in 6 projects that use this
dav-niu474Skillgift-evaluator
The PRIMARY tool for Spring Festival gift analysis and social interaction generation. Use this skill when users upload photos of gifts (alcohol, tea, supplements, etc.) to inquire about their value, authenticity, or how to respond socially. Integrates visual perception, market valuation, and HTML card generation.
Also in 5 projects that use this
dav-niu474SkillPodcast Generate
Generate podcast episodes from user-provided content or by searching the web for specified topics. If user uploads a text file/article, creates a dual-host dialogue podcast (or single-host upon request). If no content is provided, searches the web for information about the user-specified topic and generates a podcast. Duration scales with content size (3-20 minutes, ~240 chars/min). Uses z-ai-web-dev-sdk for LLM script generation and TTS audio synthesis. Outputs both a podcast script (Markdown) and a complete audio file (WAV).
Also in 5 projects that use this
Liang-MHSkillstock_analysis
获取 A 股、基金和港股的实时行情和技术分析数据
Also in 5 projects that use this
SeifBenayedSkillfile-reading
Use this skill when a file has been uploaded but its content is NOT in your context — only its path at /mnt/user-data/uploads/ is listed in an uploaded_files block. This skill is a router: it tells you which tool to use for each file type (pdf, docx, xlsx, csv, json, images, archives, ebooks) so you read the right amount the right way instead of blindly running cat on a binary. Triggers: any mention of /mnt/user-data/uploads/, an uploaded_files section, a file_path tag, or a user asking about an uploaded file you have not yet read. Do NOT use this skill if the file content is already visible in your context inside a documents block — you already have it.
Also in 5 projects that use this
- +1 more from huang-x-h
- +5 more from dav-niu474
Other versions194 projects use a version of this.
Word for word · 0
None found.
Edited · 5
- aivrar/portable-hermes-agent★ 23967% same
- wundercorp/loki★ 2867% same
- Samin12/skills★ 866% same
- rmusser01/tldw-stuff★ 267% same
- ashleysbrain/skills★ 167% same
Wrote their own version · 189
- anthropics/skills★ 189ksame name
- spinabot/brigade★ 11ksame name
- netease-youdao/LobsterAI★ 6.2ksame name
- nextlevelbuilder/goclaw★ 3.7ksame name
- jjyaoao/HelloAgents★ 3.2ksame name
- anthropics/claude-agent-sdk-demos★ 2.8ksame name
- K-Dense-AI/claude-scientific-writer★ 2.6ksame name
- OpenCoworkAI/open-cowork★ 2.2ksame name
- wanxingai/LightAgent★ 1.2ksame name
- ChenglinPoly/infiAgent★ 1.2ksame name
179 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository24 other files it gives its agents.
- AGENTS.mdAGENTS.md
- llms.txtllms.txt
- academic-referencesSkill
- annual-accountsSkill
- business-deckSkill
- business-letterSkill
- _checksSkill
- contract-draftingSkill
- diagramSkill
- docxSkill
- e-invoiceSkill
- employment-statementSkill
- html-deckSkill
- literature-searchSkill
- meeting-minutesSkill
- paperSkill
- pdfSkill
- powerpointSkill
- requirements-specSkill
- _sharedSkill
- social-posterSkill
- trade-documentsSkill
- whatsapp-exportSkill
- zotero-librarySkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
35 rules. 0 are common, 23 are distinctive, and 12 are very specific to this project.
0
Common
Most of the 188 edited versions we read keep these.
23
Distinctive
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 45
Not for the legacy .xls binary format (use LibreOffice to convert first: soffice --headless --convert-to xlsx old.xls).
- Distinctive: line 50
When the workbook must compare costs with an approved budget, ask for the missing ceiling or comparison basis before completing that …
- Distinctive: line 56
Keep known costs distinct from a complete forecast while any prices are unknown.
- Distinctive: line 63
Never manufacture a total to satisfy a requested report heading.
- Distinctive: line 67
Read the meaning of each header even when column positions change across months.
- Distinctive: line 68
Keep raw evidence and distinguish confirmed counts from unknown coverage.
- Distinctive: line 69
When some periods are absent, show the supported recorded subtotal with its coverage alongside the unknown complete-period total.
- Distinctive: line 82
Check each area, supplier or other group's known cost, row count and missing-value count against the source rows.
- Distinctive: line 85
Keep rows whose grouping value is absent in an explicit unknown group, and retain the original value separately.
- Very specific: line 102
Before delivery, run xlsx_read.py output.xlsx --check-numbers --sheet Data --range C4:E29 on each declared numeric input range.
- Distinctive: line 120
All row costs and summaries must follow those inputs.
- Distinctive: line 126
When the person asks to compare this with the next quote or report, deliver actual labelled empty input rows or columns for that next entry …
- Distinctive: line 133
Do not add financial modules the person did not request.
- Distinctive: line 137
Do this for any workbook with two or more sheets, whether or not a PDF or printout was requested.
- Very specific: line 148
Before delivery, render: soffice --headless --convert-to pdf out.xlsx --outdir /tmp/render, count pages (pdfinfo /tmp/render/out.pdf | grep …
- Very specific: line 167
Every sheet has a name that says what is on it, never Sheet1.
- Distinctive: line 171
Every formula has a saved result and none shows an error value.
- Distinctive: line 174
No merged cells. A title runs on over the empty cells beside it instead.
- Distinctive: line 176
Every column of a table has one heading, used once.
- Distinctive: line 179
No links to other workbooks, and no OFFSET or INDIRECT.
- Distinctive: line 180
No number typed into a formula.
- Distinctive: line 191
After inserting images, a library save may renumber media parts.
- Very specific: line 211
Run the helper scripts with the bash tool from this skill's scripts/ directory (every script supports --help):
- Very specific: line 260
Create: write a JSON spec (schema documented in xlsx_create.py --help and its docstring).
- Very specific: line 311
Create CSV with Python's standard csv.writer and newline="", rather than assembling escaped row separators in a string.
- Distinctive: line 329
Keep the requested rows, editable inputs and formulas complete in the native workbook.
- Distinctive: line 332
Keep necessary raw metadata in a supporting file rather than repeating long JSON records throughout the reader's workbook.
- Distinctive: line 339
Do not blindly export every raw-data tab or shrink a wide workbook until its text is unreadable.
- Distinctive: line 352
After renaming outputs, check file references in sheets and accompanying notes against the actual delivered filenames.
- Very specific: line 367
Only the first sheet lands in a CSV.
- Very specific: line 397
CSV locale traps: always pass explicit encodings (the scripts already do) and remember European CSVs often use .
- Very specific: line 408
After creating: xlsx_read.py out.xlsx --sheets and confirm sheet names, dimensions, merged ranges, and chart counts match intent.
- Very specific: line 411
After edits: re-dump the touched range.
- Very specific: line 413
After xlsx_restructure.py: read its JSON report, then re-run --formulas and --sheets to confirm references and ranges landed where expected.
- Distinctive: line 416
Before delivering any multi-sheet workbook: render to PDF and confirm every sheet is one page wide (see "Every sheet prints one page wide").
“Common” is measured: kept by at least 6 in 10 of the 188 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Xlsx Skill
First: is there a pack for this kind of document?
This skill handles the workbook. It does not know what a kind of document must carry. If the ask is for one of these and that pack is installed, stop and load it first: the pack lays the file out and checks it.
- an invoice or a credit note:
e-invoice - a quotation, order confirmation, delivery note, pro forma or purchase order:
trade-documents
Whatever language the ask is in. Come back here only for a file none of them names, or to read or change an existing one.
Work with Excel .xlsx workbooks using Python and openpyxl: build styled multi-sheet workbooks with formulas and charts, inspect or dump existing files, edit cells and structure, and convert to/from CSV. All helper scripts are argparse CLIs that print JSON and use explicit UTF-8 I/O.
Use project-specific guidance before drafting
When to Use
- Creating .xlsx reports: multiple sheets, number formats, styling, merged cells, freeze panes, autofilter, conditional formatting, charts, data-validation dropdowns, native Excel tables, defined names, hyperlinks, cell notes, sheet protection.
- Reading a workbook: sheet inventory, dumping data as JSON or CSV, listing formulas vs cached values, notes, defined names, tables.
- Editing existing files: set cells, append rows, insert/delete
rows/columns (reference-aware via
xlsx_restructure.py), copy/rename sheets, tables, names, notes, protection. - Recalculating formulas headlessly via LibreOffice
(
xlsx_recalc.py). - CSV interop with type inference and non-UTF-8 encodings.
- Not for the legacy .xls binary format (use LibreOffice to convert
first:
soffice --headless --convert-to xlsx old.xls).
Resolve the decision the workbook supports
When the workbook must compare costs with an approved budget, ask for the missing ceiling or comparison basis before completing that comparison. Do not infer a budget from spending or insert an unexplained target. A defined cost overview for a budget meeting does not by itself request a budget comparison: provide the requested totals, missing-price flags and notes without blocking on a ceiling. Ask only when the missing decision changes the requested result. Keep known costs distinct from a complete forecast while any prices are unknown.
For consolidated reports, inventory every source sheet and identify which numbers are period activity, cumulative snapshots or a documented subset. Open and closed counts from a photo appendix cannot be presented as the status of every recorded issue. Reconcile only matching populations and periods; keep unknown totals blank and state the missing source needed to complete them. Never manufacture a total to satisfy a requested report heading. For every requested indicator, provide its supported period summary or a precise reason it cannot be aggregated. Attendance marks can support a count of recorded attendance events; do not call that unique people or complete participation. Read the meaning of each header even when column positions change across months. Keep raw evidence and distinguish confirmed counts from unknown coverage. When some periods are absent, show the supported recorded subtotal with its coverage alongside the unknown complete-period total; do not discard recorded activity merely because full coverage is unavailable. Keep that distinction for each requested indicator and grouping (for example project), not only a grand total. A person-level register does not replace a requested project summary. Where a report asks for a prose summary, include that paragraph; a detailed table can support it without replacing it. Preserve missingness through formulas: a direct reference to an empty cell can produce zero. Guard missing inputs explicitly, including end-of-period snapshot references, and test a blank-input case after recalculation.
Reconcile every grouped summary
Check each area, supplier or other group's known cost, row count and missing-value count against the source rows. The groups together must reconcile to the overall counts and costs. A correct grand total does not prove the group breakdown. Keep rows whose grouping value is absent in an explicit unknown group, and retain the original value separately. Use an explicit derived grouping label for absent values, including empty cells and empty strings, rather than relying on a blank conditional-count criterion. Recalculate and compare the resulting counts with the source; formula presence alone does not prove correct grouping.
Check measurement types before totals
Monthly counts, quantities and prices may be stored as text in a source workbook. Excel SUM ignores text cells in a referenced range: 4, 4 and "4" produce 8, not 12. In the generated measurement columns, deliberately convert unambiguous numeric text to real numbers before aggregating. Preserve the original files and source wording for traceability. Do not convert identifiers, room numbers, dates or free text, and never turn missing values into zero. Confirm the source locale before interpreting ambiguous decimal/thousands separators; put unresolved values in the notes and leave the numeric input empty.
Before delivery, run xlsx_read.py output.xlsx --check-numbers --sheet Data
--range C4:E29 on each declared numeric input range. It is read-only, reports
text and other non-numeric inputs, and exits nonzero for issues. Resolve or
explicitly account for every issue. Formula inputs require separate result
verification; this check does not calculate them. Independently reconcile each
requested total with its complete source inputs and periods, then compare it
with the saved workbook's actual formula result. A syntactically valid SUM or
a successful recalculation does not prove that all intended inputs contributed.
Separate editable inputs from calculations
An operator changes numbers, not formulas. Keep source calculations as live formulas connected to plainly labelled numeric input cells. If a source price is a calculation such as a base price times a discount, expose the original base price as an editable input and keep the discounted price as a formula that references it. Carry the source discount rate and calculation unchanged; do not invent a rate. Putting the original hard-coded expression in the same cell the person must overwrite does not preserve their editing workflow. All row costs and summaries must follow those inputs. Before delivery, change one numeric input, verify the dependent discounted price and totals and that the formulas remain intact, then restore the original input and save.
Make the next action usable
When the person asks to compare this with the next quote or report, deliver actual labelled empty input rows or columns for that next entry in the same workbook. Keep existing source values and calculations, and connect the new numeric inputs to the comparison and totals. A note telling them to copy a sheet later does not deliver a ready comparison. Leave unknown suppliers, prices and dates empty; never invent another quote. Check the saved native workbook against each requested part and any later answers before delivery. Do not add financial modules the person did not request.
Every sheet prints one page wide, checked by rendering
Do this for any workbook with two or more sheets, whether or not a PDF or printout was requested. The workbook may be printed or rendered by whoever opens it, and supporting sheets (payments, rates, removed rows, unmatched items, notes) are the ones left at defaults.
- In the spec, give every sheet a
printblock:paper(A4 unless the source locale implies otherwise),orientation(landscape when a sheet has more than about five columns or any long text column),fit_width: true, andrepeat_rowsfor the header row. Also setcolumn_widthsfor every column, wide enough for the longest value, and wrap long note text rather than letting it run past the last column. - Before delivery, render:
soffice --headless --convert-to pdf out.xlsx --outdir /tmp/render, count pages (pdfinfo /tmp/render/out.pdf | grep Pages) and read the per-page text. Every sheet must be one page wide: no page may hold only columns split off another page. A short sheet should fill one page; a long one may run down several. If columns spill, widen, wrap, switch to landscape or fix that sheet's print extent, and render again. Do not delete requested columns or rows to save pages. - Repeat steps 1-2 for every saved revision. A workbook rebuilt from a new
spec must carry the
printblocks again, and an added row or column can add a page. Report the final page count only if you rendered the file you are delivering.
Every file
These hold for every workbook, whatever was asked.
- The workbook has a title.
xlsx_create.pysets it from"properties": {"title": ...}, else from the first sheet name. After editing a workbook that has none, runscripts/office_properties.py out.xlsx --title "...". - Every sheet has a name that says what is on it, never
Sheet1. - Nothing is cut. A column is at least as wide as its longest text when the next cell is filled, and wide enough to show its numbers in their format. Wrapped text needs a row tall enough for its lines.
- Every formula has a saved result and none shows an error value. Recalculate before delivering.
- Coloured text keeps a contrast of 4.5:1 against the cell fill.
- No merged cells. A title runs on over the empty cells beside it instead.
- Nothing hidden: no hidden rows, columns or sheets, and no blank sheet.
- Every column of a table has one heading, used once.
- A column of numbers holds numbers, never a number typed as text or a dash, "..", "NA" in place of one; leave the cell blank and say why in a note.
- No links to other workbooks, and no OFFSET or INDIRECT.
- No number typed into a formula. A rate, a price or any other assumption sits in its own labelled cell and the formula refers to it; only units of time and scale (12 months, 24 hours, 100 per cent, 1000) may be written in.
The last five come from the UK Government Analysis Function's "Releasing
statistics in spreadsheets" (Open Government Licence v3.0) and the FAST
Standard 02c (FAST Standard Organisation, CC BY 4.0). The pack check reads them:
python3 <skill folder>/../_checks/packcheck.py xlsx <your output>.
Preserve pictures when revising
After inserting images, a library save may renumber media parts. Do not restore old ZIP media files by filename over the new package: a new picture can reuse an old name and become a different product. If retaining original parts, give added media unique names and update the drawing relationships that reference them before combining packages. Keep content types valid. Preservation means the picture bytes at each original sheet/anchor still match, not merely that the original bytes exist somewhere in the ZIP. Reopen the saved file and compare each added anchored image with its intended source bytes or thumbnail. Check picture identity visually; a successful load, correct image count and unchanged formulas do not prove the images are right.
Prerequisites
- Python 3.10+ with
openpyxl(pip install openpyxl). No other third-party packages are needed; everything else is stdlib. - Optional: LibreOffice (
soffice) for headless recalculation or format conversion.
How to Run
Run the helper scripts with the bash tool from this skill's
scripts/ directory (every script supports --help):
python scripts/xlsx_create.py spec.json report.xlsx # build from JSON spec
python scripts/xlsx_read.py report.xlsx --sheets # inventory
python scripts/xlsx_read.py report.xlsx --json --sheet Data
python scripts/xlsx_read.py report.xlsx --formulas
python scripts/xlsx_read.py report.xlsx --check-numbers --sheet Data --range C4:E29
python scripts/xlsx_edit.py report.xlsx --sheet Data --set B2=42 --recalc
python scripts/xlsx_restructure.py report.xlsx --sheet Data --insert-rows 3:2
python scripts/xlsx_recalc.py report.xlsx
python scripts/csv_to_xlsx.py data.csv out.xlsx --encoding utf-8
python scripts/xlsx_to_csv.py report.xlsx out.csv --sheet DataAuthor the JSON spec with write, inspect script JSON output with
read or directly from stdout.
Quick Reference
| Task | Command | |
| Create workbook from spec | xlsx_create.py spec.json out.xlsx | |
| Sheet names + dimensions | xlsx_read.py f.xlsx --sheets | |
| Dump sheet as JSON | xlsx_read.py f.xlsx --json --sheet S | |
| Dump sheet as CSV | xlsx_read.py f.xlsx --csv --out d.csv | |
| List formulas + cached values | xlsx_read.py f.xlsx --formulas | |
| Check numeric inputs (read-only) | xlsx_read.py f.xlsx --check-numbers --sheet Data --range C4:E29 | |
| Set a cell / formula | xlsx_edit.py f.xlsx --set "A1==SUM(B:B)" | |
| Append a row | xlsx_edit.py f.xlsx --append '[1,"x",true]' | |
| Insert 2 rows, refs NOT shifted | xlsx_edit.py f.xlsx --insert-rows 3:2 | |
| Insert 2 rows, refs shifted | xlsx_restructure.py f.xlsx --insert-rows 3:2 | |
| Delete a column, refs shifted | xlsx_restructure.py f.xlsx --delete-cols B | |
| Create a native table | xlsx_edit.py f.xlsx --add-table Sales:A1:C9 | |
| Append inside a table | --table-append 'Sales=["West",5]' | |
| List tables | xlsx_edit.py f.xlsx --list-tables | |
| Defined names | --define-name "Rates='Data'!$B$2:$B$9" / --delete-name Rates / xlsx_read.py f.xlsx --names | |
| Hyperlink | `--hyperlink "A1=https://example.com | Docs"` |
| Cell note | `--note "B2=Check this | Reviewer"; read via xlsx_read.py f.xlsx --notes` |
| Protect sheet (see Pitfalls) | --protect your-password --unlock B2:B9 | |
| Recalculate via LibreOffice | xlsx_recalc.py f.xlsx | |
| Copy / rename sheet | --copy-sheet Src:New --rename-sheet Old:New | |
| Force recalc on open | xlsx_edit.py f.xlsx --recalc | |
| CSV -> styled xlsx | csv_to_xlsx.py in.csv out.xlsx | |
| xlsx -> CSV | xlsx_to_csv.py f.xlsx out.csv --encoding utf-8 |
Procedure
- Create: write a JSON spec (schema documented in
xlsx_create.py --helpand its docstring). Each sheet supportsrows(scalars or styled cell objects), sparsecellsoverrides,column_widths,row_heights,merges,freeze_panes,autofilter,conditional_formats(cell_is rules and color scales),charts(bar/line/pie from cell ranges),validations(list dropdowns),tables(native Excel tables with a style name), andprotection. Workbook-leveldefined_namesmaps names to refs. Cell objects also takehyperlinkandnote. Typed values: JSON numbers/bools pass through; dates use{"value": "2026-01-31", "type": "date"}. Number formats are Excel format strings: currency"$#,##0.00", percent"0.0%", date"yyyy-mm-dd". - Formulas: set with
"formula": "SUM(B2:B9)"in the spec or--set "C1==SUM(A:A)"in the editor. When writing formulas, add"full_calc_on_load": true(spec) or--recalc(editor); this sets the workbook'sfullCalcOnLoadflag so Excel/LibreOffice recompute everything on open. openpyxl itself NEVER evaluates formulas. - Read:
--sheetsfor inventory (names, dimensions, merged ranges, chart count, tables, protection, defined names),--json/--csvfor data,--formulasto pair each formula string with its cached result,--notesfor cell comments,--namesfor defined names. Cached results exist only if the file was last saved by a real spreadsheet app; files fresh from openpyxl returnnullthere. To materialize results headlessly runxlsx_recalc.py file.xlsx(uses LibreOffice; prints{"recalculated": false, ...}and exits 0 whensofficeis absent), then reload with--data-only. If recalculation produces formula errors, the helper returns nonzero with sheet/cell details and leaves the input and destination unchanged. Repair those errors before claiming valid totals;recalculated: truealone is not a successful result. - Edit:
xlsx_edit.pyapplies renames/copies first, then structural row/column changes, then--set/--append. It edits in place unless--outis given — copy the file first if you need the original. - Restructure: for insert/delete on sheets that have formulas,
merges, tables, or filters, use
xlsx_restructure.pyinstead ofxlsx_edit.py. It rewrites formula references on ALL sheets (absolute$refs, ranges, cross-sheet refs), shifts merges, autofilter, freeze panes, validation and conditional-format ranges, table refs, defined names, and row/column dimensions, then prints a JSON report including anot_shiftedlist. Rules and limits:references/restructuring.md. - CSV interop:
csv_to_xlsx.pyinfers int/float/bool/ISO-date per cell and styles the header row;xlsx_to_csv.pywrites ISO dates and blank strings for empty cells. Both default to UTF-8 and accept--encoding(e.g.utf-8-sigfor Excel-friendly BOM,cp1252for legacy Windows exports).
Verify saved CSV files
Create CSV with Python's standard csv.writer and newline="", rather than
assembling escaped row separators in a string. After saving, parse the actual
file again before delivery. Compare exact headers, field counts and expected
data-record count against the source; quoted commas and quoted multiline
cells are valid CSV and must remain intact.
Run csv_verify.py purchases.csv --headers '["date","item","quantity","unit_price","currency"]' --rows 3
with the columns and row count from the current request/source, not these
example values. The helper is read-only and exits nonzero on mismatched
headers, ragged records or missing rows. Fix the generated file and rerun
before saying it is ready. Verify source values, blank unknowns and unchanged
inputs separately; a shape pass does not establish factual accuracy. Never
globally replace literal backslash-n sequences in an existing CSV: they may
be legitimate cell content.
Deliver readable views with compact sources
Separate the recipient's working tables from raw extraction or audit data. Keep the requested rows, editable inputs and formulas complete in the native workbook. Use a compact source table keyed to the relevant row or group, with file/page or URL, retrieval date when applicable and a short factual note. Keep necessary raw metadata in a supporting file rather than repeating long JSON records throughout the reader's workbook. Preserve original evidence.
For a requested PDF, select the sheets and columns that answer its purpose.
Set and check the print layout for every intended printed sheet, including
source notes; the main sheet settings do not keep another sheet’s labels and
details together.
Do not blindly export every raw-data tab or shrink a wide workbook until its
text is unreadable. Use suitable page orientation, repeated headers and page
breaks, or a labelled summary view whose totals and missing-value counts
reconcile to the native rows. Retain access to requested detail. Inspect the
saved PDF at normal reading size and fix clipping, tiny text and blank pages
before delivery; a successful conversion proves none of those qualities.
For each populated cover or supporting sheet included in the render, explicitly
set paper size, orientation, fit-to-width and the intended print extent. Give
wrapped rows enough height after final text edits, and keep text readable rather
than forcing the whole sheet onto one page.
xlsx_create.py sheet specs take a print key (paper, orientation,
fit_width, repeat_rows, area) that sets this in the saved file.
After renaming outputs, check file references in sheets and accompanying notes against the actual delivered filenames. Preserve source citations separately from links to newly generated files, and use portable relative links where supported. A reference to an old filename is not a working handoff.
Converting to PDF
LibreOffice converts headlessly (also works for CSV export of a single sheet):
soffice --headless --convert-to pdf report.xlsx --outdir out/
soffice --headless --convert-to csv report.xlsx --outdir out/ # 1st sheet onlyOnly the first sheet lands in a CSV; for other sheets use
xlsx_to_csv.py --sheet NAME. If soffice is missing, install
LibreOffice or hand the file to the user unconverted.
Pitfalls
- openpyxl does not calculate. Formula results are available only
via
load_workbook(path, data_only=True)and only when the file was previously saved by Excel/LibreOffice. Otherwise you getNone. - Read
"preserved"in the JSON ofxlsx_edit.pyandxlsx_restructure.py.true: every part the edit did not touch (charts, pictures, sparklines, pivots) was kept byte for byte, and row/column moves rewrote formulas, names, tables, chart ranges and anchors.falsewithpreserve_refused: the edit could not be saved safely that way and ran on the stock path, which may drop what openpyxl does not model and whosexlsx_edit.pyinsert/delete does not shift references. Then name what may be lost in the hand-back, usexlsx_restructure.pyfor moves, and read itsnot_shiftedlist andreferences/restructuring.md. - Sheet protection is NOT security.
--protectsets the standard xlsx sheet-protection hash: it signals "don't edit this" to well-behaved apps and nothing more. Anyone can strip it by editing the zip's XML or unchecking it in LibreOffice. Never rely on it for confidentiality or integrity; it does not encrypt anything. data_only=Truethen save silently discards all formulas (cached values replace them). Never save a workbook loaded that way unless that is the goal.- Charts and pictures survive an edit only when
"preserved": true. On the stock path openpyxl rewrites charts and drops sparklines and newer conditional formats; check the saved file before handing it back. - CSV locale traps: always pass explicit encodings (the scripts
already do) and remember European CSVs often use
;delimiters and decimal commas — use--delimiter ';'and expect strings like"12,5"to stay strings. - Dates are datetimes: Excel stores dates as serial numbers;
openpyxl returns
datetime/dateobjects. Dumps here emit ISO strings. - Sheet names are capped at 31 chars and reject
[ ] : * ? / \.
Verification
- After creating:
xlsx_read.py out.xlsx --sheetsand confirm sheet names, dimensions, merged ranges, and chart counts match intent. - Dump data with
--jsonand compare against the source values. - After edits: re-dump the touched range; if formulas were written,
confirm
--formulaslists them and that--recalcwas applied. - After
xlsx_restructure.py: read its JSON report, then re-run--formulasand--sheetsto confirm references and ranges landed where expected. - Before delivering any multi-sheet workbook: render to PDF and confirm every sheet is one page wide (see "Every sheet prints one page wide"). Recalculation and a formula check do not establish this.
- For a full visual check, open in LibreOffice:
soffice --headless --convert-to pdf out.xlsxand inspect the PDF.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

