HTML优先演示文稿制作 (HTML-First Deck)
一种两阶段的方法,用于构建用户可以在PowerPoint中编辑的自定义、美观的演示文稿。
为何采用此工作流
PowerPoint是迭代视觉设计最糟糕的地方——速度慢、繁琐、难以保持一致性。 HTML/CSS是迭代的最佳场所:你可以快速布局幻灯片、预览并优化间距、颜色和层级。但最终的交付物必须是真正的、可编辑的.pptx,这样用户才能在他们自己的工具中调整措辞和品牌(每张幻灯片导出为图像对他们来说毫无用处)。
所以:在HTML中设计,以原生PPTX交付。 你既能快速迭代,又能得到一个可编辑的结果。
此文件夹中的内容:
| 文件 | 用途 |
|---|---|
references/html_prototype.html | 第一阶段起点:三张幻灯片,品牌颜色作为CSS变量,幻灯片导航 |
scripts/pptx_helpers.py | 第二阶段辅助库:几何、调色板、页眉/页脚/卡片/药丸形状/关键要点组件 |
scripts/render_diagram.py | 将代码绘制的SVG渲染为高分辨率PNG |
scripts/render_pptx.ps1 | 将.pptx的每张幻灯片导出为PNG以供检查(Windows + PowerPoint) |
examples/example_deck.py | 一个可运行的三张幻灯片演示文稿,基于辅助库构建 |
examples/example_diagram.py | 一个可运行的图表生成器,展示了图表部分中的所有技术 |
语调——像顾问一样写标题,而不是文案
在写任何标题、副标题或正文之前,请阅读此部分。 布局正确但文字错误会生成一个用户需要重写的演示文稿,这比没有演示文稿更糟糕。这适用于任何面向客户或同事的内容——演示文稿、HTML幻灯片、仪表盘、状态报告、单页文档。
LLM生成幻灯片的默认风格是夸张的广告文案。大多数商业受众并不喜欢。除非用户另有要求,否则请以资深顾问面向高管受众的风格写作:平实、陈述性、具体、一次成型。
规则
标题陈述这个幻灯片是关于什么的。它不进行表演。
命名内容。如果一个只浏览标题的读者无法重构论点,那么标题就失败了。有标签和编号总比耍小聪明好——第一阶段:退款泄漏告诉了读者他们所处的位置;我们开始的那个则没有传达任何信息,迫使他们继续阅读以了解。
避免使用的结构
| 不要 | 为何失败 | 要这样写 |
|---|---|---|
仪表盘报告。 / 它不解释。 | 两段式“铺垫然后点睛之笔”。读起来像口号,而不是发现。 | 当前仪表盘报告了数字,但没有进行分析 |
他们因为仪表盘放弃了最后一个工具。 / 不要再卖给他们另一个仪表盘。 | 同样是两段式,而且还说教读者。 | 为什么另一个仪表盘无法解决此问题 |
我们开始的那个: | 一个冒号逗引,隐藏答案以制造悬念。 | 第一阶段:退款泄漏 |
接下来是如何修复。 | 过于口语化,且回答了没人问的问题。 | 建议修复方案和构建估算 |
三件事。然后我们去证明它。 | 断奏式碎片用于制造节奏。 | 本次会议需要的内容 |
摆在桌上的是什么。 | 用习语代替描述。 | 我们交付的内容 |
每两周一次,一个带有数字的发现。 | 用口号代替标签。 | 时间线 |
只有能看到所有四个供应商的人才会发现这个。 | 修辞性铺垫。 | 为什么我们的团队适合做这项工作 |
还避免:以反问句作为标题;使用单个词语的戏剧性(陷阱,战术,收尾)作为主要标题;使用断句产生冲击力;em破折号揭秘;关键在于;任何听起来像需要朗读出来的东西。
具体来说
- 标题: 名词短语或平实陈述。
分析方法。数据需求与交付日期。给客户的问题。运行第一阶段所需的条件。 - 给工作编号。 阶段、梯队、步骤。
第一阶段到第八阶段,梯队 1/2/3。编号使计划清晰易读,并让人们在会议中有可参考的内容。 - 副标题 承载限定词,而不是玩笑:
第一阶段 · 方法,数据请求 · 梯队 1。 - 正文: 带有主语和动词的完整句子。一次性把话说明白,而不是用三次重复并加强语气。
- 保持具体。 平实不等于模糊。
年初至今 840 万美元,退款率为 12.5%就是完全正确的。数字、名称、日期和来源是使其可信的关键。 - 谨慎使用粗体——用于段落中承载重量的那个短语,而不是为了节奏。
- 引文是例外。 客户的原话可以保持原样,真正有力的单句可以放在引语框中——但要作为发现来陈述,而不是作为口号。
百分比必须附有基数
百分比很好——继续使用。但没有基数的百分比是无法判断的。"前10%的代理人"在20名代理人中意味着2个人,在1000名代理人中意味着100个人;读者无法判断这是一个模式还是两个个体。
- 每次百分比代表人员、事物或事件的份额时,请将计数与百分比放在一起。
前6名代理人(60人中的10%)·4,100名客户(820,000中的0.5%)·供应商A收到了1200万美元,占所有退款金额(2400万美元)的一半。 - 群体较小时,用数字而非百分比开头。 少于约30个项目时,计数就是发现:
6名代理人签发了18,000美元优于10%的代理人签发了20%。 - 两个百分比并排需要两者都有基数。 "20%的钱来自12%的联系人"只有在读者知道这是18,000美元中的90,000美元和30,000个联系人中的3,600个时才有用。
- 指明分母。 说明百分比是关于什么的:
占8月退款金额的,占至少申报一次的客户的,占工作天数超过10天的代理人的。 - 尽可能说明百分比在金钱或人员方面意味着什么。 "3%被支付到了不同的账户"应改为
1,500笔退款(15万美元),占年度总额的3%。 - 整体份额的发现需要整体份额图表,例如100%堆叠条形图,这样读者无需计算就能看到一半。
自查:对于页面上的每个%,读者能否在不离开句子的情况下回答“占多少?” 如果不能,请添加计数。
交付前自查
按顺序阅读演示文稿的标题,只看标题。如果它们读起来像目录,那就对了。如果它们读起来像推销,请重写。
第一阶段——在HTML中原型设计
编写 deck.html,在16:9画布(1280×720)上为每张幻灯片设置一个 .slide div。将品牌颜色放在 :root CSS变量中(从用户的模板中提取——参见下面的“品牌”部分)。布局页眉、章节标题、卡片、标注、表格。在此处迭代直到设计正确——通过打开它/截取屏幕截图来预览,并获得用户对结构和外观的批准。
references/html_prototype.html 是一个准备好的起点(封面、一个包含标题+三卡片+关键要点的幻灯片、一个图片幻灯片、页脚),带有CSS变量调色板。阅读并适配它。
这个阶段是设计沙盒。不要完善每个词——要搞定布局系统(页眉/页脚样式、卡片样式、字体缩放、强调色用法),因为第二阶段会镜像它。
使原型像幻灯片一样可导航
始终在 </body> 之前添加此小脚本,以便HTML预览像PowerPoint一样前进——点击(或→/↓/空格键)进入下一张幻灯片,←/↑返回。 这使第一阶段的审查感觉像在演示,并且仅限HTML(无需带入第二阶段)。
高亮文本时绝不能翻页。 人们选择幻灯片上的文本来复制它。一次拖拽以click事件结束,因此普通的点击处理程序会在复制中途跳到下一张幻灯片。下面的脚本在鼠标在按下和释放之间移动超过5px,或者选择文本时忽略点击。真实的点击仍然会前进。
点击必须从被点击的幻灯片前进,而不是基于滚动位置的猜测。在某些窗口大小下,猜测会选错幻灯片,因此一次点击会跳两张幻灯片。按键(→/←)仍然可以使用滚动位置,因为没有东西可以点击。
<script>
/* 像幻灯片一样预览:点击或 →/↓/空格键 = 下一张,←/↑ = 上一张。选择文本不会前进。 */
(function(){
var slides=[].slice.call(document.querySelectorAll('.slide'));
function next(){ var y=scrollY+10; return slides.find(function(s){return s.offsetTop>y;}) || null; }
function prev(){ var y=scrollY-10, p=null; slides.forEach(function(s){ if(s.offsetTop<y) p=s; }); return p; }
function to(s){ if(s) s.scrollIntoView({behavior:'smooth',block:'start'}); }
var downX=0,downY=0;
addEventListener('mousedown',function(e){ downX=e.clientX; downY=e.clientY; });
addEventListener('click',function(e){
if(e.target.closest('a,button,input,textarea,select'))return;
/* 高亮文本,或拖拽鼠标,不是点击幻灯片 */
var sel=window.getSelection&&String(window.getSelection()); if(sel&&sel.trim())return;
if(Math.abs(e.clientX-downX)>5||Math.abs(e.clientY-downY)>5)return;
/* 从被CLICK的幻灯片前进,而不是基于滚动位置的猜测 */
var s=e.target.closest('.slide'); to(s ? slides[slides.indexOf(s)+1] : next());
});
addEventListener('keydown',function(e){
if(['ArrowRight','ArrowDown',' ','PageDown'].indexOf(e.key)>-1){e.preventDefault();to(next());}
else if(['ArrowLeft','ArrowUp','PageUp'].indexOf(e.key)>-1){e.preventDefault();to(prev());}
});
})();
</script>
如果演示文稿保留在浏览器中(一个HTML幻灯片),请在此处停止:第一阶段就是交付物。
第二阶段——生成本地可编辑的PPTX
使用python-pptx重建经批准的设计,使每个元素都可编辑。使用捆绑的辅助库 scripts/pptx_helpers.py——将其复制到演示文稿文件夹中。它提供16:9几何、品牌调色板块以及你将在每张幻灯片上重用的组件:
new_prs(),blank_slide(prs),body_bg(slide)add_header(slide, title, meta),add_footer(slide, left, right)add_section_title,add_subtitleadd_text(...)— 支持字符串、段落列表或混合样式的run:[[("粗体部分", {"bold": True}), ("普通部分", {"color": MUTED})]]add_rect,add_card(顶部/左侧强调条纹),add_pill,bulleted,add_takeawayadd_image(slide, path, x, y, w)— 按图片自身比例放置图片save_deck(prs, path)— 保存,并且如果文件被锁定/打开则切换到新文件名
结构(参见 examples/example_deck.py 了解可运行的三幻灯片示例):
from pptx_helpers import *
def slide_intro(prs): ... # 每张幻灯片一个构建器函数
def slide_cards(prs): ...
def main():
prs = new_prs()
slide_intro(prs); slide_cards(prs)
print(save_deck(prs, DECK_DIR / "My Deck.pptx"))
经过实践验证的规则(这些可防止常见故障)
- 切勿覆盖用户已打开的文件。 PowerPoint会锁定该文件;简单的
prs.save()会抛出PermissionError。save_deck()通过将文件名增加到v2,v3... 来处理此问题。将工作副本放在明显的位置,并告诉用户哪个文件是最新的。 - 所有内容都构建为形状/文本,而不是图片。 这就是重点——他们必须能够编辑它。对于密集的比较,使用真实的表格(
slide.shapes.add_table)。 - 在每个run上显式设置字体(python-pptx不会可靠地继承主题字体)。
- 禁用自动形状的默认阴影(
shape.shadow.inherit = False)并清除其默认文本——辅助库已经这样做了。 - 每张幻灯片一个构建器 + 一个按顺序列出它们的
main()。 在此处重新编号页脚。
预览/验证循环(这样做——不要未经查看就交付)
每次构建后,将幻灯片渲染为PNG并实际查看它们;修复溢出/间距;重新构建。
- Windows(已安装PowerPoint):
生成powershell -NoProfile -File scripts/render_pptx.ps1 -pptx "My Deck.pptx" -outdir previewpreview/s1.png,s2.png……它以只读方式打开文件,因此即使用户打开了演示文稿也能工作,并且如果PowerPoint已经运行,它不会关闭它。 - 没有PowerPoint — 如果可用,使用
libreoffice --headless --convert-to pdf(或转换为PNG)。
然后查看PNG,调整构建器,重新运行。迭代直到清晰。
品牌(颜色+字体)
不要默认使用一个调色板。从用户上下文中提取品牌:读取一个 .pptx 模板的主题(ppt/theme/theme1.xml → <a:clrScheme>),公司的网站/CSS,或询问2-3种颜色。在HTML的 :root 变量和PPTX的 pptx_helpers.py 顶部的BRAND块中一次性设置它们,以使两个阶段匹配。将 WORDMARK_PATH 设置为一个Logo PNG以在页眉中显示品牌,或保留为None。两个文件中附带的颜色是中性占位符;请替换它们。
幻灯片内的图表——用代码绘制,不要生成
对于幻灯片上的主体视觉元素(流程图、管道图、漏斗图、架构或过程图),不要手动放置数十个PowerPoint形状,并且不要使用AI图像生成器。图像模型是为照片和艺术设计的。对于图表,它们会失败:模糊的文字、拼写错误的标签、未对齐的形状、偏离品牌的颜色,并且没有任何内容是可编辑的。
相反,编写一个SVG(用代码定义的矢量图:<path>, <circle>, <rect>, <text>,带有渐变和滤镜)并将其渲染为高分辨率PNG。计算机会根据规格绘制每一条线,因此它是像素锐利、完全符合品牌、可重复且易于编辑的(更改颜色代码或文字并重新渲染)。
给用户一个类比:向图像模型请求图表就像让一位艺术家凭记忆徒手绘制蓝图。编写代码来绘制它就像CAD——一个专用工具——每次都精确无误。
用于:管道/流程/漏斗图、架构图、过程图、概念图…
... [为翻译而截断]