Files
iofficeai--officecli/examples/excel/sheet-settings.py
T
wehub-resource-sync 8cb1f9f479
Publish SDK (PyPI) / publish (push) Has been cancelled
Publish SDK (npm) / publish (@aionui/officecli-sdk) (push) Has been cancelled
SDK smoke / smoke (windows-latest) (push) Has been cancelled
Publish SDK (npm) / publish (@officecli/officecli-sdk) (push) Has been cancelled
Publish SDK (npm) / publish (@officecli/sdk) (push) Has been cancelled
Publish SDK (npm) / publish (officecli-sdk) (push) Has been cancelled
SDK smoke / smoke (macos-latest) (push) Has been cancelled
SDK smoke / smoke (ubuntu-latest) (push) Has been cancelled
Skill parity / diff (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:09:29 +08:00

183 lines
6.8 KiB
Python

#!/usr/bin/env python3
"""
Sheet Settings Showcase — generates sheet-settings.xlsx exercising the xlsx
`sheet` element's sheet-level property surface (schemas/help/xlsx/sheet.json):
the per-*worksheet* settings on <sheetView>, <pageSetup>, <headerFooter>,
<sheetPr>, <sheetProtection>, and the sheet's defined-names. Distinct from the
workbook-level settings in workbook-settings.{sh,py}.
Four themed sheets: freeze panes, print setup, headers/footers, display +
protection (plus a sorted sheet and a hidden sheet).
SDK twin of sheet-settings.sh. Drives the officecli Python SDK
(`pip install officecli-sdk`) and maps onto the shell script one-for-one:
officecli.create(...) ≈ officecli create + open (file + resident)
doc.send({...}) ≈ one officecli set/add (one call each, no batch)
doc.close() ≈ officecli close (flush to disk)
Usage:
pip install officecli-sdk # plus the `officecli` binary on PATH
python3 sheet-settings.py
"""
import os
import officecli # pip install officecli-sdk
FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "sheet-settings.xlsx")
print("\n==========================================")
print(f"Generating sheet-settings showcase: {FILE}")
print("==========================================")
doc = officecli.create(FILE, "--force") # create the .xlsx + start its resident
COLS = "ABCDEFGH"
def cell(path, **props): # one cell write = one `officecli set`
doc.send({"command": "set", "path": path, "props": props})
def sheet(path, **props): # one sheet-container `set`
doc.send({"command": "set", "path": path, "props": props})
def add_sheet(**props): # one `officecli add --type sheet`
doc.send({"command": "add", "parent": "/", "type": "sheet", "props": props})
def hdr(name, *titles): # bold header row (row 1)
for i, title in enumerate(titles):
cell(f"/{name}/{COLS[i]}1", value=title, **{"font.bold": "true"})
def rows(name, start, data): # data rows from `start` down
for r, values in enumerate(data, start=start):
for i, v in enumerate(values):
cell(f"/{name}/{COLS[i]}{r}", value=str(v))
# --- Sheet 1 — Freeze Panes (rename Sheet1) ---
print("\n--- 1-Freeze-Panes ---")
sheet("/Sheet1", name="1-Freeze-Panes")
hdr("1-Freeze-Panes", "Date", "Region", "Product", "Units", "Revenue")
rows("1-Freeze-Panes", 2, [
("2026-01", "North", "Widget", 120, 1140),
("2026-01", "South", "Gadget", 95, 1045),
("2026-02", "East", "Widget", 140, 1225),
("2026-02", "West", "Gizmo", 88, 968),
("2026-03", "North", "Gadget", 132, 1452),
])
# freeze panes: B2 freezes header row 1 AND first column A
sheet("/1-Freeze-Panes", freeze="B2")
# --- Sheet 2 — Print Setup ---
print("--- 2-Print-Setup ---")
add_sheet(name="2-Print-Setup")
hdr("2-Print-Setup", "Item", "Qty", "Unit", "Total")
rows("2-Print-Setup", 2, [
("Screws", 500, 0.02, 10.00),
("Bolts", 300, 0.05, 15.00),
("Washers", 800, 0.01, 8.00),
("Nuts", 450, 0.03, 13.50),
("Anchors", 120, 0.12, 14.40),
])
# print-only settings — verify via get, not visual render
sheet("/2-Print-Setup", **{
"orientation": "landscape",
"paperSize": "9", # 9 = A4
"fitToPage": "1x1", # fit to one page
"printArea": "A1:D6",
"printTitleRows": "1:1", # repeat row 1 at top of each page
"printTitleCols": "A:A", # repeat column A at left
"margin.top": "1.0in", "margin.bottom": "1.0in",
"margin.left": "0.5in", "margin.right": "0.5in",
"margin.header": "0.3in", "margin.footer": "0.3in",
})
# --- Sheet 3 — Headers & Footers ---
print("--- 3-Headers-Footers ---")
add_sheet(name="3-Headers-Footers")
hdr("3-Headers-Footers", "Quarter", "Sales", "Target")
rows("3-Headers-Footers", 2, [
("Q1", 45000, 40000),
("Q2", 52000, 48000),
("Q3", 61000, 55000),
("Q4", 58000, 60000),
])
# Excel format codes pass through verbatim:
# &L left &C center &R right &P page num &N page count &D date &F file
sheet("/3-Headers-Footers",
header="&LQuarterly Report&C2026 Sales&R&D",
footer="&LConfidential&CPage &P of &N&R&F")
# --- Sheet 4 — Display & Protection ---
print("--- 4-Display-Protection ---")
add_sheet(name="4-Display-Protection")
hdr("4-Display-Protection", "Metric", "Value")
rows("4-Display-Protection", 2, [
("Users", 1250),
("Sessions", 8400),
("Bounce", 32),
("Retention", 68),
])
# display: tab color, hide gridlines + headings, zoom, AutoFilter, RTL layout
sheet("/4-Display-Protection", **{
"tabColor": "C0392B",
"gridlines": "false",
"headings": "false",
"zoom": "125",
"autoFilter": "A1:B5",
"direction": "rtl",
})
# protection: enable + legacy password hash (do last — a protected sheet
# can't be sorted, so sorting is on its own sheet below)
sheet("/4-Display-Protection", protect="true", password="secret123")
# --- Sheet 5 — Sorted (sort can't coexist with protect) ---
print("--- 5-Sorted ---")
add_sheet(name="5-Sorted", tabColor="27AE60")
hdr("5-Sorted", "Name", "Score")
rows("5-Sorted", 2, [
("Carol", 88),
("Alice", 95),
("Bob", 72),
("Dave", 60),
])
sheet("/5-Sorted", sort="B desc") # highest score first
# --- Sheet 6 — Hidden at creation ---
print("--- 6-Hidden ---")
add_sheet(name="6-Hidden", hidden="true")
cell("/6-Hidden/A1", value="Hidden data sheet")
# --- Get round-trip: confirm sheet-level keys read back (over the pipe) ---
print("\n--- Round-trip readback ---")
for path, keys in [
("/1-Freeze-Panes", ["freeze"]),
("/2-Print-Setup", ["orientation", "paperSize", "fitToPage", "printArea"]),
("/3-Headers-Footers", ["header", "footer"]),
("/4-Display-Protection", ["tabColor", "gridlines", "headings", "zoom",
"autoFilter", "direction", "protect"]),
("/5-Sorted", ["sort", "tabColor"]),
("/6-Hidden", ["hidden", "visibility"]),
]:
node = doc.send({"command": "get", "path": path})
fmt = node.get("data", {}).get("results", [{}])[0].get("format", {})
got = {k: fmt[k] for k in keys if k in fmt}
print(f" {path}: {got}")
# --- Validate over the pipe (in-session, no extra process) ---
# `save` first so element order is normalized on disk before we validate —
# otherwise the pre-save in-memory model can report a transient schema-order
# note (e.g. sheetPr) that the save-time reserialization fixes.
print("\n--- Validate ---")
doc.send({"command": "save"})
v = doc.send({"command": "validate"})
print(" Validation passed: no errors found." if v.get("success")
else f" {v.get('warnings')}")
doc.close() # stop the resident (flushes to disk)
print(f"\nCreated: {FILE}")