Files
wehub-resource-sync 8cb1f9f479
Publish SDK (PyPI) / publish (push) Waiting to run
Publish SDK (npm) / publish (@aionui/officecli-sdk) (push) Waiting to run
Publish SDK (npm) / publish (@officecli/officecli-sdk) (push) Waiting to run
Publish SDK (npm) / publish (@officecli/sdk) (push) Waiting to run
Publish SDK (npm) / publish (officecli-sdk) (push) Waiting to run
SDK smoke / smoke (windows-latest) (push) Waiting to run
SDK smoke / smoke (macos-latest) (push) Waiting to run
SDK smoke / smoke (ubuntu-latest) (push) Waiting to run
Skill parity / diff (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:09:29 +08:00

190 lines
8.4 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Content Controls Showcase — generates content-controls.docx exercising the docx
`sdt` (structured document tag / content control) property surface
(schemas/help/docx/sdt.json).
An `sdt` is a content control: a bounded region Word treats as a single form
field. Block-level SDTs (added at /body) wrap paragraphs. Every control shares
alias / tag / lock / placeholder; each variant then adds its own props:
text — plain-text field (text=)
richText — rich formatted field (text=, lock=contentLocked)
dropDown — pick-one, typing disabled (items=, dropDown.lastValue=)
comboBox — pick-one OR free type (items= display|value, comboBox.lastValue=)
date — date picker (format=, date.fullDate/calendar/lid/storeMappedDataAs=)
picture — image placeholder (type=picture)
group — locked grouping wrapper (type=group, lock=sdtContentLocked)
checkbox — check-box toggle (type=checkbox, checked=)
The document models a small employee-intake form.
Like examples/word/document-formatting.py, this drives the officecli Python SDK
(`pip install officecli-sdk`): one resident, writes shipped over the pipe.
Usage:
python3 content-controls.py
"""
import os
import sys
import subprocess
try:
import officecli # pip install officecli-sdk
except ImportError:
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
"..", "..", "sdk", "python"))
import officecli
FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "content-controls.docx")
def para(text, **props):
return {"command": "add", "parent": "/body", "type": "paragraph",
"props": {"text": text, **props}}
def sdt(**props):
return {"command": "add", "parent": "/body", "type": "sdt", "props": props}
print("\n==========================================")
print(f"Generating content-controls showcase: {FILE}")
print("==========================================")
with officecli.create(FILE, "--force") as doc:
# ----------------------------------------------------------------------
# Title + intro
# ----------------------------------------------------------------------
print("\n--- Title + intro ---")
doc.batch([
para("Employee Intake Form", style="Title"),
para("Complete every field. Grey boxes are content controls — click one "
"and Word treats it as a single fillable region.", style="Subtitle"),
])
# ----------------------------------------------------------------------
# 1. plainText — the employee's full name
# alias (Word label) / tag (data key) / text (initial content) / lock /
# placeholderText (docPart gallery reference).
# ----------------------------------------------------------------------
print("--- plainText: Full Name ---")
doc.batch([
para("Full name", style="Heading2"),
sdt(type="text", alias="Full Name", tag="fullName",
text="[Enter full legal name]",
lock="unlocked", placeholderText="DefaultPlaceholder"),
])
# ----------------------------------------------------------------------
# 2. dropDown — department (pick-one, typing disabled)
# items= comma list, dropDown.lastValue= the current pick.
# ----------------------------------------------------------------------
print("--- dropDown: Department ---")
doc.batch([
para("Department", style="Heading2"),
sdt(type="dropdown", alias="Department", tag="department",
items="Sales,Engineering,Human Resources,Finance,Operations",
**{"dropDown.lastValue": "Engineering"}),
])
# ----------------------------------------------------------------------
# 3. comboBox — office location (pick-one OR free-type)
# items= uses display|value form; comboBox.lastValue= the stored value.
# ----------------------------------------------------------------------
print("--- comboBox: Office Location ---")
doc.batch([
para("Primary office", style="Heading2"),
sdt(type="combobox", alias="Office Location", tag="office",
items="New York|NYC,London|LON,Singapore|SIN,Remote|REMOTE",
**{"comboBox.lastValue": "LON"}),
])
# ----------------------------------------------------------------------
# 4. date — start date (calendar picker)
# format= display mask; date.fullDate ISO value; calendar / lid / mapping.
# ----------------------------------------------------------------------
print("--- date: Start Date ---")
doc.batch([
para("Start date", style="Heading2"),
sdt(type="date", alias="Start Date", tag="startDate",
format="yyyy-MM-dd",
**{"date.fullDate": "2026-02-01T00:00:00Z",
"date.calendar": "gregorian",
"date.lid": "en-US",
"date.storeMappedDataAs": "dateTime"}),
])
# ----------------------------------------------------------------------
# 5. picture — profile photo placeholder
# ----------------------------------------------------------------------
print("--- picture: Profile Photo ---")
doc.batch([
para("Profile photo", style="Heading2"),
sdt(type="picture", alias="Profile Photo", tag="photo"),
])
# ----------------------------------------------------------------------
# 6. richText — reviewer notes (formatted, multi-run field)
# lock=contentLocked freezes the content (editable=false on readback).
# ----------------------------------------------------------------------
print("--- richText: Reviewer Notes ---")
doc.batch([
para("Reviewer notes", style="Heading2"),
sdt(type="richtext", alias="Reviewer Notes", tag="notes",
text="Manager may add formatted commentary here.",
lock="contentLocked"),
])
# ----------------------------------------------------------------------
# 7. group — a locked wrapper around an approval line
# sdtContentLocked blocks both deletion and content edits.
# ----------------------------------------------------------------------
print("--- group: Approval Block ---")
doc.batch([
para("Approval", style="Heading2"),
sdt(type="group", alias="Approval Block", tag="approval",
text="Approved by HR — signature on file.",
lock="sdtContentLocked"),
])
# ----------------------------------------------------------------------
# 8. checkbox — the HR approval toggle (real Word check-box control).
# checked=true → ☒ (2612) / false → ☐ (2610). Emits <w14:checkbox>.
# ----------------------------------------------------------------------
print("--- checkbox: HR approved ---")
doc.batch([
para("HR approved", style="Heading2"),
sdt(type="checkbox", alias="Approved", tag="hrApproved",
checked="true"),
])
# ----------------------------------------------------------------------
# Post-add tweak via `set` — alias / tag / lock / text are settable.
# (Per-type props like dropDown.lastValue are add/get-only, not settable.)
# ----------------------------------------------------------------------
print("--- set: rename + lock the department control ---")
doc.send({"command": "set", "path": "/body/sdt[2]",
"props": {"alias": "Home Department", "lock": "sdtLocked"}})
doc.send({"command": "save"})
# ----------------------------------------------------------------------
# Get round-trip: confirm each control's canonical props read back
# ----------------------------------------------------------------------
print("\n--- Round-trip readback (query sdt) ---")
for i in range(1, 9):
node = doc.send({"command": "get", "path": f"/body/sdt[{i}]"})
fmt = node.get("data", {}).get("results", [{}])[0].get("format", {})
checked = f" checked={fmt['checked']}" if "checked" in fmt else ""
print(f" sdt[{i}] type={fmt.get('type')} alias={fmt.get('alias')!r} "
f"tag={fmt.get('tag')} lock={fmt.get('lock', 'unlocked')}{checked}")
print("\n--- Validate (fresh process, from disk) ---")
r = subprocess.run(["officecli", "validate", FILE], capture_output=True, text=True)
print(" ", (r.stdout or r.stderr).strip().split("\n")[0])
print(f"\nCreated: {FILE}")