Files
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

198 lines
8.0 KiB
Python

#!/usr/bin/env python3
"""
PowerPoint OLE embedded objects — embed .xlsx / .docx binary payloads in a deck.
SDK twin of ole-embed.sh (officecli CLI). Both produce an equivalent
ole-embed.pptx. This one drives the **officecli Python SDK**
(`pip install officecli-sdk`): a resident is started per file and every element
is shipped over the named pipe. Each item is the same
`{"command","parent","type","props"}` dict you'd put in an `officecli batch`
list; `doc.send(...)` ships one and returns its envelope.
This script:
1. Builds two source payloads with officecli: a tiny .xlsx and a .docx
2. Synthesizes two distinct preview thumbnail PNGs (Pillow)
3. Builds a 2-slide PPTX demoing OLE embedding:
- slide 1: embed the .xlsx (Excel.Sheet.12) and the .docx (Word.Document.12),
each with an explicit preview= thumbnail so they render visibly
- slide 2: WITH preview= vs WITHOUT — a deliberate teaching contrast
4. Reads back contentType / fileSize / progId / relId via `get`
IMPORTANT: officecli does NOT auto-generate the Office live-preview image for an
embedded OLE object. Without preview=, the object embeds and validates fine, but
real PowerPoint renders it as a BLANK rectangle in static/print view — it only
becomes visible after the user double-clicks to activate it. Supply preview= for
any OLE object you want visible in a static view.
The embedded source files (data.xlsx, data.docx) and the preview PNGs live in
this example dir alongside the deck — they are the meaningful inputs the embed
step consumes.
Requirements:
pip install Pillow officecli-sdk # plus the `officecli` binary on PATH
Usage:
python3 ole-embed.py
"""
import os
import sys
try:
from PIL import Image, ImageDraw
except ImportError:
print("ERROR: Pillow not installed. Run: pip install Pillow")
sys.exit(1)
# --- locate the SDK: prefer an installed `officecli-sdk`, else the in-repo copy
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
HERE = os.path.dirname(os.path.abspath(__file__))
FILE = os.path.join(HERE, "ole-embed.pptx")
XLSX = os.path.join(HERE, "data.xlsx")
DOCX = os.path.join(HERE, "data.docx")
THUMB_XLSX = os.path.join(HERE, "thumb-xlsx.png")
THUMB_DOCX = os.path.join(HERE, "thumb-docx.png")
def add(doc, parent, typ, **props):
"""Ship one `add` item over the pipe; return the parsed envelope."""
return doc.send({"command": "add", "parent": parent, "type": typ, "props": props})
def make_thumbs(xlsx_path, docx_path):
# Excel-styled thumbnail (green) for the .xlsx embed
img = Image.new("RGB", (240, 160), (33, 115, 70))
d = ImageDraw.Draw(img)
d.rectangle((8, 8, 231, 151), outline=(255, 255, 255), width=4)
d.text((30, 40), "Q1 Revenue", fill=(255, 255, 255))
d.text((30, 90), "(embedded .xlsx)", fill=(200, 230, 210))
img.save(xlsx_path)
# Word-styled thumbnail (blue) for the .docx embed
img = Image.new("RGB", (240, 160), (43, 87, 154))
d = ImageDraw.Draw(img)
d.rectangle((8, 8, 231, 151), outline=(255, 255, 255), width=4)
d.text((30, 40), "Quarterly Memo", fill=(255, 255, 255))
d.text((30, 90), "(embedded .docx)", fill=(205, 218, 240))
img.save(docx_path)
def build_xlsx(path):
"""A tiny spreadsheet payload."""
if os.path.exists(path):
os.remove(path)
with officecli.create(path, "--force") as x:
x.send({"command": "set", "path": "/sheet[1]/A1", "props": {"value": "Q1 Revenue"}})
x.send({"command": "set", "path": "/sheet[1]/A2", "props": {"value": "North"}})
x.send({"command": "set", "path": "/sheet[1]/B2", "props": {"value": "1200"}})
x.send({"command": "set", "path": "/sheet[1]/A3", "props": {"value": "South"}})
x.send({"command": "set", "path": "/sheet[1]/B3", "props": {"value": "980"}})
x.send({"command": "save"})
def build_docx(path):
"""A tiny Word memo payload."""
if os.path.exists(path):
os.remove(path)
with officecli.create(path, "--force") as w:
add(w, "/body", "paragraph", text="Quarterly Memo", bold="true", size="16")
add(w, "/body", "paragraph", text="Revenue is up 12% quarter over quarter.")
w.send({"command": "save"})
def main():
if os.path.exists(FILE):
os.remove(FILE)
build_xlsx(XLSX)
build_docx(DOCX)
make_thumbs(THUMB_XLSX, THUMB_DOCX)
print(f"Building {FILE} ...")
with officecli.create(FILE, "--force") as doc:
# ── Slide 1: embed an .xlsx and a .docx, each with a preview= ─────────
add(doc, "/", "slide")
add(doc, "/slide[1]", "textbox",
text="Embedded OLE objects — Excel + Word packages",
size="24", bold="true",
x="0.5in", y="0.3in", width="12in", height="0.6in")
# Embed the spreadsheet. Double-clicking the object opens it in-place.
# progId=Excel.Sheet.12 marks it as a modern .xlsx package.
# preview= gives it a visible face in static view (officecli won't bake one).
add(doc, "/slide[1]", "ole",
src=XLSX,
progId="Excel.Sheet.12",
preview=THUMB_XLSX,
x="1.5in", y="1.8in", width="3.5in", height="2.5in")
add(doc, "/slide[1]", "textbox",
text="src=data.xlsx progId=Excel.Sheet.12 preview=thumb-xlsx.png",
size="12", italic="true",
x="1.5in", y="4.4in", width="5in", height="0.4in")
# Embed the Word memo. progId=Word.Document.12 marks it as a modern .docx.
# preview= gives it a visible face in static view (officecli won't bake one).
add(doc, "/slide[1]", "ole",
src=DOCX,
progId="Word.Document.12",
preview=THUMB_DOCX,
x="6.5in", y="1.8in", width="3.5in", height="2.5in")
add(doc, "/slide[1]", "textbox",
text="src=data.docx progId=Word.Document.12 preview=thumb-docx.png",
size="12", italic="true",
x="6.5in", y="4.4in", width="5in", height="0.4in")
# ── Slide 2: WITH preview= vs WITHOUT — a deliberate teaching contrast ─
add(doc, "/", "slide")
add(doc, "/slide[2]", "textbox",
text="preview= is the reliable path to a visible OLE object",
size="24", bold="true",
x="0.5in", y="0.3in", width="12in", height="0.6in")
# WITH preview= — the thumbnail is drawn in the object frame in static
# view. add-time only (Set ignores this key).
add(doc, "/slide[2]", "ole",
src=XLSX,
progId="Excel.Sheet.12",
preview=THUMB_XLSX,
x="1.5in", y="1.8in", width="3.5in", height="2.5in")
add(doc, "/slide[2]", "textbox",
text="src=data.xlsx preview=thumb-xlsx.png (renders visibly)",
size="12", italic="true",
x="1.5in", y="4.4in", width="4.5in", height="0.4in")
# WITHOUT preview= — embeds and validates fine, but real PowerPoint
# renders a BLANK rectangle in static view; it only appears once
# double-clicked/activated. officecli does NOT bake the live preview.
add(doc, "/slide[2]", "ole",
src=XLSX,
progId="Excel.Sheet.12",
x="6.5in", y="1.8in", width="3.5in", height="2.5in")
add(doc, "/slide[2]", "textbox",
text="src=data.xlsx (no preview — blank until opened in PowerPoint)",
size="12", italic="true",
x="6.5in", y="4.4in", width="5in", height="0.4in")
doc.send({"command": "save"})
# ── Inspect: Get surfaces read-only readbacks (src is NOT echoed) ─────
for path in ("/slide[1]/ole[1]", "/slide[1]/ole[2]"):
env = doc.send({"command": "get", "path": path})
print(f"{path}: {env.get('data') if isinstance(env, dict) else env}")
# context exit closes the resident, flushing the deck to disk.
print(f"Created: {FILE}")
if __name__ == "__main__":
main()