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/選項物件 — 每次呼叫都應建立新的物件。 - 陰影
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 沒有原生形式的圖表類型(如桑基圖、網路圖、和弦圖)時,才以圖片形式插入。 - 預設圖表渲染得很簡陋 — 沒有標題、沒有資料標籤、使用過時的調色盤。請設定
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>以保留間距,並在標題、章節標題和行內標籤(如狀態:、負責人:)的<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 渲染,它會替換它沒有的字體 — 而對於某些字體,替代字體具有不同的寬度,因此您的 QA 預覽可能會顯示真實簡報中不會出現的文字溢出(或剛好符合)。為了讓您的 QA 值得信賴:
- 安全字體(在 QA 中的渲染寬度與實際一致,且隨 Office 提供):Arial、Calibri、Cambria、Times New Roman、Courier New、Bookman Old Style、Century Schoolbook。對於正文和任何需要考慮尺寸合適性的文字,請使用這些字體。
- 零 QA 風險的個性化標題:將安全列表中的襯線標題字體(Cambria、Bookman Old Style、Century Schoolbook)與安全列表中的無襯線正文(Calibri 或 Arial)搭配使用。您可以獲得視覺對比,同時不必擔心溢出檢查不可靠。
- 如果使用者要求使用安全列表之外的字體(例如 Georgia 或 Trebuchet MS):在使用者要求的地方使用它,但請為這些容器預留額外空間(約 10%),並且不要信任這些元素上 QA 的文字尺寸合適性 — 該字體的預覽是近似的。如果使用者未指定,正文文字請優先使用安全列表中的字體。
- QA 不可靠的字體(替代字體寬度不同 — 溢出檢查可能錯誤):Georgia、Trebuchet MS、Impact、Arial Black、Garamond、Consolas、Palatino Linotype。Calibri Light 的替代字體因環境而異;請將其視為 QA 不可靠。可用於標題/強調文字但要保留空間;不要信任這些字體上的 QA 文字尺寸合適性。
- 切勿預設使用 Aptos — Office 2023 年後的新預設字體在此處沒有尺寸兼容的替代字體,而且舊版 Office 安裝中可能沒有,因此在兩端都不可靠。
| 元素 | 大小 |
|---|---|
| 投影片標題 | 36-44pt 粗體 |
| 章節標題 | 20-24pt 粗體 |
| 正文 | 14-16pt |
| 圖說 | 10-12pt 淡化 |
…
[為翻譯而截斷]