PPTX 建立、編輯與分析
.pptx 是一個包含 XML 檔案的 ZIP 壓縮檔。根據任務選擇處理方式:
| 任務 | 處理方式 |
|---|---|
| 建立新簡報 | 撰寫 pptxgenjs 腳本 — 請見下方注意事項 |
| 編輯現有簡報,或從範本建立 | 解壓縮 → 編輯 ppt/slides/slideN.xml → 重新壓縮 |
| 讀取內容 | markitdown deck.pptx(每個幻燈片一個區塊,位於 <!-- Slide number: N --> 標記下);視覺化網格:python scripts/thumbnail.py deck.pptx |
腳本
路徑相對於此技能的目錄。其他部分皆為純 Python、node 或 shell 腳本。
| 腳本 | 功能 |
|---|---|
scripts/thumbnail.py deck.pptx [prefix] | 建立每個幻燈片的標籤網格,用於挑選範本版面。僅適用 .pptx。可傳入 prefix — 預設為 thumbnails,若在同一目錄中處理多個簡報,會覆蓋彼此的網格 |
scripts/add_slide.py unpacked/ slide2.xml [--after slideN.xml] | 複製一個幻燈片(或 slideLayoutN.xml),並處理所有套件簿記工作。也可直接對 .pptx 使用,加上 -o out.pptx 參數 |
scripts/clean.py unpacked/ | 刪除不再被參照的幻燈片、媒體與關聯檔案。在 <p:sldIdLst> 最終確定後執行 |
scripts/office/validate.py deck.pptx [--original src.pptx] | 執行結構描述、關聯、內容類型、圖表與幻燈片檢查;每個失敗項目會指出修正方式。若處理從範本衍生的簡報,請傳入 --original — 它會將結構描述檢查基準對齊至範本,避免範本本身的 XSD 錯誤被誤認為是您的錯誤 |
scripts/office/soffice.py --headless --convert-to pdf deck.pptx | LibreOffice 包裝器 — 在此沙箱中單純使用 soffice 會停滯 |
使用 pptxgenjs 建立 — 注意事項
pptxgenjs 已預先安裝 — 請勿先執行 npm install;直接撰寫腳本並使用 require('pptxgenjs')。僅在 require 失敗時才執行 npm install pptxgenjs。模型已了解 API;以下是常見陷阱:
- 在新增幻燈片之前,請先設定
pres.layout。 預設畫布是LAYOUT_16x9= 10" × 5.625",不是 13.3" 寬。超出邊界的座標會被寫入,但不會被裁切 — 形狀只是不在幻燈片上。(LAYOUT_WIDE是 13.3" × 7.5"。) - 十六進位顏色:永遠不要用
#,永遠不要用 8 位數。 使用color: "FF0000"。"#FF0000"或將 Alpha 值嵌入十六進位(例如"00000020")都會損毀檔案。若要設定半透明:在填滿與圖片上使用transparency: 0-100,在陰影上使用opacity: 0.0-1.0— 每個屬性若用錯地方會被忽略。 - pptxgenjs 會原地修改選項物件(首次使用時將值轉換為 EMU)。請勿在兩個
add*呼叫之間共用同一個shadow/options 物件 — 每次請建立新的物件。 - 陰影
offset必須 >= 0 — 負數偏移會損毀檔案。若要向上投射陰影,請使用angle: 270搭配正數偏移。 letterSpacing會被忽略 — 實際的選項是charSpacing。- 清單: 每個項目使用
bullet: true,永遠不要使用字面•(會造成雙重項目符號)。每個陣列項目(除了最後一個)請設定breakLine: true。使用paraSpaceAfter來分隔項目符號段落,不要使用lineSpacing(會造成巨大間距)。 - 每個輸出檔案請使用一個新的
new pptxgen()實例 — 請勿重複使用同一個實例。 rectRadius僅適用於ROUNDED_RECTANGLE,不適用於RECTANGLE。- 不支援漸層填滿 — 請改用漸層圖片作為背景。
- 文字方塊有內建的內部邊距 — 當文字需要與相同 x 位置的形狀、線條或圖示對齊時,請設定
margin: 0。 - 演講者備註請使用
slide.addNotes("...")(純文字,每個幻燈片一次),不要在幻燈片上使用文字方塊。 - 保持圖表原生。 對於 PowerPoint 能繪製的圖表,請一律使用
addChart()(若要組合圖表,請傳入{type, data, options}陣列)。對於程式庫未提供的 PowerPoint 原生功能(例如趨勢線、誤差線),請自行計算額外的數列,或後處理產生的 OOXML — 不要退而使用渲染圖片。只有 PowerPoint 沒有原生形式的圖表類型(例如 Sankey、網路圖、和弦圖)才以圖片形式插入。 - 預設圖表呈現空白 — 沒有標題、沒有資料標籤、使用過時的調色盤。請設定
showTitle+title、showValue: true+dataLabelPosition、chartColors: [...](從您的調色盤),並隱藏框架(catAxisLabelColor/valAxisLabelColor、valGridLine: { color, size }、catGridLine: { style: "none" }、若是單一數列則使用showLegend: false)。 - 在堆疊長條圖或堆疊直條圖上,
dataLabelPosition必須是ctr、inEnd或inBase。outEnd會損毀檔案。 - 使用
secondaryValAxis/secondaryCatAxis的組合圖表數列,需要在圖表選項中同時提供valAxes和catAxes,每個項目各兩個條目。 若缺少這些設定,pptxgenjs 會寫入未宣告的軸線 ID,PowerPoint 會捨棄該圖表並回報檔案損毀。僅提供valAxes是不夠的。 - 執行
writeFile()後,請執行python scripts/office/validate.py deck.pptx。 它會回報上述兩種圖表錯誤以及 PowerPoint 會拒絕的幻燈片 XML 缺陷,並指出每個問題的修正方式。請在產生器中修正這些問題,不要手動編輯壓縮後的 XML。 - 請勿重新排列
<p:presentation>的子元素。 pptxgenjs 會在<p:sldIdLst>之後馬上寫入<p:notesMasterIdLst>,並將兩個母版指向同一個主題部分。PowerPoint 可以正常讀取這種結構 — 若移動該元素,同一個簡報將無法開啟。 - 圖示: 將
react-icons渲染為 SVG(使用ReactDOMServer.renderToStaticMarkup),使用sharp以 >=256px 解析度進行光柵化,並透過addImage({ data: "image/png;base64," + buf.toString("base64") })插入 — 必須包含image/png;base64,前綴(react-icons、react、react-dom和sharp已預先安裝 — 僅在 require 失敗時才執行npm install react-icons react react-dom sharp)。
編輯現有簡報與範本
先挑選版面:python scripts/thumbnail.py template.pptx template-thumbs 會建立每個幻燈片的標籤網格,並印出建立的檔案 — template-thumbs.jpg,若超過 12 張幻燈片則會分割為 template-thumbs-N.jpg。請務必傳入第二個參數,並以簡報名稱命名。 它預設為 thumbnails,因此同一目錄中兩個簡報的縮圖會互相覆蓋 — 第一個簡報的縮圖會消失(範本分析用 — 視覺品質確認需要轉換為圖片中的全解析度渲染;它僅接受 .pptx,因此請先將 .potx 複製為 .pptx 名稱)。將它與 markitdown 搭配使用,將每個內容區塊對應到範本幻燈片,並變化版面 — 不要將所有區塊都放在同一個標題與項目符號幻燈片上。
python3 -c "import sys,zipfile; zipfile.ZipFile(sys.argv[1]).extractall('unpacked')" deck.pptx
python scripts/add_slide.py unpacked/ slide2.xml --after slide2.xml # 複製一個幻燈片(或 slideLayoutN.xml);印出新幻燈片的路徑
# 重新排序 / 刪除幻燈片 = 編輯 ppt/presentation.xml 中的 <p:sldIdLst>
python scripts/clean.py unpacked/ # 刪除操作後:移除孤立幻燈片、媒體、關聯檔案
# 在 ppt/slides/slideN.xml 中編輯幻燈片內容
(cd unpacked && rm -f ../out.pptx && zip -Xr ../out.pptx .) # 從目錄內部壓縮;先移除,否則已刪除的部分會殘留
python scripts/office/validate.py out.pptx --original deck.pptx
- 在編輯任何幻燈片內容之前,請先完成所有結構性工作 — 新增、刪除、重新排序。
add_slide.py會直接複製幻燈片檔案,因此在編輯後複製會複製已編輯的內容;而clean.py會刪除任何在<p:sldIdLst>中遺失的幻燈片,包括您剛剛寫入的幻燈片。 - 請勿手動複製幻燈片檔案 —
add_slide.py會處理新幻燈片所需的所有註冊,並回報其建立了什麼(Created ppt/slides/slide17.xml from slide2.xml)。它也可以直接對檔案使用:add_slide.py deck.pptx slide2.xml -o out.pptx— 請務必使用-o,否則它會原地改寫輸入的簡報。 複製的幻燈片仍然參照其來源的圖表/SmartArt/內嵌物件部分,而不是複製它們,因此編輯一個幻燈片的圖表會改變另一個幻燈片的圖表。 - 如果您使用
python-pptx,有三件事它無法做到:複製幻燈片(其唯一的進入點是add_slide(layout))、透過text_frame.text = "..."保留格式(這會將段落壓縮為單一無樣式的執行 — 請改用run.text指派)、或讀取大多數範本圖稿使用的 SVG/EMF(add_picture會引發UnidentifiedImageError)。 - 舊版
.ppt必須先轉換:python scripts/office/soffice.py --headless --convert-to pptx file.ppt。.potx範本的解壓縮與封裝方式相同 — 輸出時請保留.potx副檔名。 - 若要重複使用範本圖示或圖片,請複製已包含該圖示或圖片的幻燈片或版面。
填寫範本時:
- 如果您要編寫 XML 轉換腳本,請使用
defusedxml.minidom進行解析 — 透過xml.etree.ElementTree來回轉換 OOXML 會改寫命名空間前綴並損毀簡報。 - 範本欄位 ≠ 來源項目。 如果範本顯示 4 位團隊成員,而您只有 3 位,請刪除第 4 位成員的整個群組(圖片 + 文字方塊),而不僅僅是文字 — 然後在品質確認中檢查是否有孤立的視覺元素。
- 每個清單項目一個
<a:p>— 請勿將多個項目合併到一個段落中。複製同級<a:pPr>以保留間距,並在標題、區塊標題和內聯標籤(例如Status:、Owner:)的<a:rPr>上設定b="1"。 - 讓項目符號繼承自版面;僅在需要覆蓋時才新增
<a:buChar>、<a:buAutoNum>(編號)或<a:buNone>— 不要在文字中使用字面•。 - 含有前導或尾隨空白的文字需要在
<a:t>上設定xml:space="preserve"。
設計想法
不要建立無聊的幻燈片。 白底黑字的純項目符號無法令人印象深刻。請考慮從此列表中為每個幻燈片挑選一些想法。
開始之前
- 選擇一個大膽、與內容相關的色彩調色盤:調色盤應感覺是為此主題特別設計。如果將您的顏色套用到完全不同的簡報後仍然「可行」,那表示您沒有做出足夠具體的選擇。
- 主導性重於均等性:一個顏色應佔主導地位(60-70% 的視覺重量),搭配 1-2 個輔助色調和一個鮮明的強調色。永遠不要讓所有顏色擁有相等的重量。
- 深色/淺色對比:標題和結論幻燈片使用深色背景,內容幻燈片使用淺色背景(「三明治」結構)。或者,為了營造高級感,可以從頭到尾都使用深色。
- 確定一個視覺主題:選擇一個獨特的元素並重複使用 — 圓角圖片框、彩色圓圈中的圖示。在每個幻燈片上貫徹使用。不要使用色彩條或強調條紋作為主題(請見避免列表)。
色彩調色盤
選擇與您主題相符的顏色 — 不要預設使用常見的藍色。使用這些調色盤作為靈感:
| 主題 | 主色 | 次要色 | 強調色 |
|---|---|---|---|
| 午夜行政 | 1E2761(海軍藍) | CADCFC(冰藍) | FFFFFF(白) |
| 森林與苔蘚 | 2C5F2D(森林綠) | 97BC62(苔蘚綠) | F5F5F5(奶油白) |
| 珊瑚能量 | F96167(珊瑚) | F9E795(金) | 2F3C7E(海軍藍) |
| 暖陶土 | B85042(陶土) | E7E8D1(沙色) | A7BEAE(鼠尾草綠) |
| 海洋漸層 | 065A82(深藍) | 1C7293(青綠) | 21295C(午夜藍) |
| 炭灰極簡 | 36454F(炭灰) | F2F2F2(米白) | 212121(黑) |
| 青綠信任 | 028090(青綠) | 00A896(海沫綠) | 02C39A(薄荷) |
| 莓果與奶油 | 6D2E46(莓果) | A26769(塵土玫瑰) | ECE2D0(奶油) |
| 鼠尾草寧靜 | 84B59F(鼠尾草) | 69A297(尤加利) | 50808E(石板灰) |
| 櫻桃大膽 | 990011(櫻桃紅) | FCF6F5(米白) | 2F3C7E(海軍藍) |
每個幻燈片
每個幻燈片都需要一個視覺元素 — 圖片、圖表、圖示或形狀。只有文字的幻燈片容易被遺忘。
版面選項:
- 雙欄(文字左側,插圖右側)
- 圖示 + 文字行(彩色圓圈中的圖示,粗體標題,下方描述)
- 2x2 或 2x3 網格(一側是圖片,另一側是內容區塊網格)
- 半出血圖片(全左側或右側)搭配內容疊加
資料呈現:
- 大數字重點提示(大數字 60-72pt,下方小標籤)
- 比較欄(之前/之後、優點/缺點、並排選項)
- 時間軸或流程圖(編號步驟、箭頭)
視覺修飾:
- 區塊標題旁的小彩色圓圈中的圖示
- 重點數據或標語使用斜體強調文字
字體排印
您寫入 .pptx 的字體名稱是由使用者的 PowerPoint 渲染,而非此環境。 您的視覺品質確認是透過 LibreOffice 渲染,它會替換其沒有的字體 — 對於某些字體,替代字體的寬度不同,因此您的品質確認預覽可能會顯示文字溢出(或適合),而實際簡報不會有這種情況。為確保品質確認可信:
- 安全字體(在品質確認中寬度真實,且隨 Office 提供):Arial、Calibri、Cambria、Times New Roman、Courier New、Bookman Old Style、Century Schoolbook。這些字體用於正文和任何需要考慮空間的內容。
- 零品質確認風險的個性化標題:將安全列表中的襯線標題字體(Cambria、Bookman Old Style、Century Schoolbook)與安全列表中的無襯線正文(Calibri 或 Arial)配對。您可以在不犧牲可靠溢出檢查的情況下獲得視覺對比。
- 如果使用者要求安全列表之外的字體(例如 Georgia 或 Trebuchet MS):在使用者要求的地方使用它,但將這些容器的大小設定得稍大(約 10%),並且不要依賴這些元素上的品質確認文字適應 — 該字體的預覽僅為近似值。如果使用者未指定,正文文字請優先使用安全列表字體。
- 品質確認不可靠的字體(替代字體寬度不同 — 溢出檢查可能錯誤):Georgia、Trebuchet MS、Impact、Arial Black、Garamond、Consolas、Palatino Linotype。Calibri Light 的替代會因環境而異;請視為品質確認不可靠。可用於帶有餘量的標題/強調文字;不要依賴這些字體的品質確認文字適應。
- 永遠不要預設使用 Aptos — Office 2023 年後的預設字體在此環境中沒有公制相容的替代字體,而且在舊版 Office 中也缺失,因此在兩端都不可靠。
| 元素 | 大小 |
|---|---|
| 幻燈片標題 | 36-44pt 粗體 |
| 區塊標題 | 20-24pt 粗體 |
| 正文 | 14-16pt |
| 標題說明 | 10-12pt 低調 |