Make your PPT by Marp

Posted on Sat 21 June 2025 in Journal

Abstract Journal on 2025-06-21
Authors Walter Fan
 Category    learning note  
Status v1.0
Updated 2025-06-21
License CC-BY-NC-ND 4.0

作为一个程序员, 免不了在写代码之余, 写写PPT. 传统的作法是, 先找一个 PPT 模板, 构思好内容, 一页一页的添加内容, 修改样式, 调整布局

其实, 用 Markdown 写 PPT 是一个不错的选择, 这些年我写文档最常用的格式就是 Markdown, 写好之后, 让 Cursor, 通义灵码之类的 AI 工具帮忙校对修饰一番, 然后用如下命令一键生成 PDF 或者 PPT:

marp presentation.md --pdf -o presentation.pdf

或者

marp presentation.md --pptx -o presentation.pptx

下面具体介绍一下如何使用 Marp 来写 PPT.

Marp is a Markdown presentation framework with theme and export support.

  • Install Marp CLI:

在终端中执行如下命令: npm install -g @marp-team/marp-cli

  • Write slides.md
---
marp: true
title: Hello
---

# Slide 1

- Point A
- Point B

---

# Slide 2

![bg](background.jpg)

实用技巧和进阶用法

1. 主题设置

Marp 内置了几个主题,你可以在文档开头指定:

---
marp: true
theme: gaia
---

常用主题包括: - default: 默认主题,简洁干净 - gaia: 现代感强,适合商务演示 - uncover: 大字体,适合远距离展示

2. 页面布局和样式

---
marp: true
theme: gaia
size: 16:9
backgroundColor: #fff
---

# 居中标题
<!-- _class: lead -->

这是一个居中的标题页

---

# 左右分栏布局
<!-- _class: lead -->

<div class="columns">
<div>

## 左侧内容
- 要点1
- 要点2
- 要点3

</div>
<div>

## 右侧内容
- 要点A
- 要点B
- 要点C

</div>
</div>

<style>
.columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}
</style>

3. 背景图片和渐变

# 背景图片
![bg](https://example.com/image.jpg)

---

# 渐变背景
<!-- _backgroundColor: linear-gradient(45deg, #405de6, #5851db) -->
<!-- _color: white -->

白色文字配渐变背景

---

# 半透明背景
![bg opacity:0.3](background.jpg)

图片背景,降低透明度

4. 完整示例:技术分享PPT

下面是一个完整的技术分享PPT示例:

---
marp: true
theme: gaia
size: 16:9
backgroundColor: #fff
---

<!-- _class: lead -->

# 🚀 微服务架构实践
## 从单体到分布式的演进之路

**分享人:** 张三  
**时间:** 2025年6月21日

---

# 📋 今日议程

1. 🏢 单体架构的挑战
2. 🔧 微服务架构设计
3. 📊 实施过程与经验
4. 🎯 最佳实践总结

---

<!-- _class: lead -->

# 🏢 单体架构的挑战

---

# 单体架构现状

<div class="columns">
<div>

## 😰 面临的问题
- 代码库庞大,维护困难
- 技术栈固化,升级风险高
- 团队协作冲突频繁
- 部署耗时,回滚困难

</div>
<div>

## 📈 业务增长压力
- 用户量:10万 → 100万
- 数据量:1GB → 1TB
- 功能模块:10个 → 50个
- 开发团队:5人 → 30人

</div>
</div>

---

# 🔧 微服务架构设计

![bg right:40%](https://example.com/microservices.png)

## 核心原则
- **单一职责**:每个服务专注一个业务域
- **自治性**:独立开发、部署、扩展
- **去中心化**:服务间通过API通信
- **容错性**:服务降级与熔断机制

---

# 📊 技术栈选型

| 组件 | 选择 | 理由 |
|------|------|------|
| 服务注册 | Consul | 服务发现和健康检查 |
| 负载均衡 | Nginx | 高性能反向代理 |
| API网关 | Kong | 统一入口,限流鉴权 |
| 消息队列 | RabbitMQ | 异步解耦,削峰填谷 |
| 数据库 | PostgreSQL | 强一致性,ACID保证 |
| 缓存 | Redis | 高性能键值存储 |

---

# 🎯 实施效果

部署频率:每月1次 → 每天多次 交付周期:2-3个月 → 1-2周 故障恢复:2-4小时 → 10-30分钟 新人上手:1-2个月 → 1-2周

<!-- _class: lead -->

## 📈 业务指标提升
- 系统可用性:99.9% → 99.99%
- 响应时间:500ms → 100ms
- 并发用户:1K → 10K

---

# 💡 最佳实践

## 1. 服务拆分策略
- 按业务领域拆分(DDD)
- 避免过度拆分
- 保持数据独立性

## 2. 监控与运维
- 分布式链路追踪
- 统一日志收集
- 自动化部署流水线

## 3. 团队协作
- 康威定律:组织架构决定系统架构
- 建立清晰的服务边界
- 制定统一的开发规范

---

<!-- _class: lead -->

# 🙏 谢谢大家!

**Q&A 环节**

📧 联系方式:zhangsan@company.com  
🐙 GitHub:github.com/zhangsan

<style>
.columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}
</style>

5. 导出和使用技巧

生成不同格式的文件:

# 生成PDF
marp slides.md --pdf -o presentation.pdf

# 生成PowerPoint
marp slides.md --pptx -o presentation.pptx

# 生成HTML(支持演示模式)
marp slides.md --html -o presentation.html

# 监听文件变化,实时预览
marp slides.md --watch --preview

6. 高级定制

你还可以创建自定义主题:

/* custom-theme.css */
@import 'gaia';

section {
  font-family: 'Roboto', sans-serif;
}

section.lead h1 {
  font-size: 3em;
  background: linear-gradient(45deg, #667eea, #764ba2);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

section.lead h2 {
  color: #666;
  font-weight: 300;
}

然后在Markdown中引用:

---
marp: true
theme: custom-theme
---

其他脚本生成PPT的方法

1. Python-pptx

Python-pptx是一个强大的Python库,可以编程方式创建和修改PowerPoint文档。

安装和基本用法:

pip install python-pptx

示例代码:

from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN

# 创建演示文稿
prs = Presentation()

# 添加标题页
title_slide_layout = prs.slide_layouts[0]
slide = prs.slides.add_slide(title_slide_layout)
title = slide.shapes.title
subtitle = slide.placeholders[1]

title.text = "Python自动化PPT"
subtitle.text = "用代码生成专业演示文稿"

# 添加内容页
bullet_slide_layout = prs.slide_layouts[1]
slide = prs.slides.add_slide(bullet_slide_layout)
shapes = slide.shapes

title_shape = shapes.title
body_shape = shapes.placeholders[1]

title_shape.text = '核心优势'
tf = body_shape.text_frame
tf.text = '完全编程控制'

# 添加更多要点
p = tf.add_paragraph()
p.text = '数据驱动生成'
p.level = 1

p = tf.add_paragraph()
p.text = '批量处理能力'
p.level = 1

# 添加图表
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE

chart_data = CategoryChartData()
chart_data.categories = ['Q1', 'Q2', 'Q3', 'Q4']
chart_data.add_series('销售额', (20.4, 30.6, 45.9, 60.2))

slide = prs.slides.add_slide(prs.slide_layouts[5])
chart = slide.shapes.add_chart(
    XL_CHART_TYPE.COLUMN_CLUSTERED, 
    Inches(2), Inches(2), Inches(6), Inches(4.5), 
    chart_data
).chart

# 保存文件
prs.save('presentation.pptx')

高级功能示例:

# 批量生成多个PPT
import pandas as pd

def generate_monthly_report(month, data):
    prs = Presentation()

    # 标题页
    slide = prs.slides.add_slide(prs.slide_layouts[0])
    slide.shapes.title.text = f"{month}月度报告"

    # 数据页
    slide = prs.slides.add_slide(prs.slide_layouts[1])
    slide.shapes.title.text = "关键指标"

    # 从DataFrame生成表格
    rows, cols = data.shape
    table = slide.shapes.add_table(rows+1, cols, 
                                   Inches(1), Inches(2), 
                                   Inches(8), Inches(5))

    # 填充表格
    for i, column in enumerate(data.columns):
        table.table.cell(0, i).text = column

    for i in range(rows):
        for j in range(cols):
            table.table.cell(i+1, j).text = str(data.iloc[i, j])

    prs.save(f'report_{month}.pptx')

# 使用示例
data = pd.DataFrame({
    '指标': ['用户数', '收入', '转化率'],
    '本月': [1000, 50000, 0.05],
    '上月': [900, 45000, 0.045]
})

generate_monthly_report('2025-06', data)

2. Reveal.js

Reveal.js是一个基于HTML5的演示框架,支持丰富的交互效果。

基本结构:

<!doctype html>
<html>
<head>
    <link rel="stylesheet" href="reveal.js/css/reveal.css">
    <link rel="stylesheet" href="reveal.js/css/theme/white.css">
</head>
<body>
    <div class="reveal">
        <div class="slides">
            <section>
                <h1>欢迎使用Reveal.js</h1>
                <h3>Web演示框架</h3>
            </section>

            <section>
                <h2>垂直导航</h2>
                <section>
                    <h3>向下滑动</h3>
                </section>
                <section>
                    <h3>子页面</h3>
                </section>
            </section>

            <section data-background="#dddddd">
                <h2>背景颜色</h2>
                <pre><code class="hljs">
function hello() {
    console.log("Hello World!");
}
                </code></pre>
            </section>
        </div>
    </div>

    <script src="reveal.js/js/reveal.js"></script>
    <script>
        Reveal.initialize({
            hash: true,
            plugins: [ RevealHighlight, RevealNotes ]
        });
    </script>
</body>
</html>

支持Markdown:

<section data-markdown>
    <textarea data-template>
        ## 页面标题

        - 要点1
        - 要点2
        - 要点3

        Note: 这是演讲者备注
    </textarea>
</section>

3. Pandoc

Pandoc是一个强大的文档转换工具,支持多种格式互转。

Markdown转PPT:

# 转换为PowerPoint
pandoc slides.md -o presentation.pptx

# 转换为reveal.js
pandoc slides.md -t revealjs -s -o presentation.html

# 转换为PDF Beamer
pandoc slides.md -t beamer -o presentation.pdf

Markdown语法:

% 演示标题
% 作者姓名
% 日期

# 第一页

这是第一页内容

## 子标题

- 要点1
- 要点2

# 第二页

![图片](image.png)

::: notes
这是演讲者备注
:::

4. LaTeX Beamer

对于学术演示,LaTeX Beamer是经典选择。

基本模板:

\documentclass{beamer}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}

\title{演示标题}
\author{作者姓名}
\date{\today}

\begin{document}

\frame{\titlepage}

\begin{frame}
\frametitle{目录}
\tableofcontents
\end{frame}

\section{介绍}
\begin{frame}{什么是LaTeX Beamer}
\begin{itemize}
    \item 专业的学术演示工具
    \item 优秀的数学公式支持
    \item 多种主题可选
\end{itemize}
\end{frame}

\begin{frame}{数学公式}
爱因斯坦质能方程:
\begin{equation}
E = mc^2
\end{equation}
\end{frame}

\end{document}

5. 自动化脚本示例

结合多种工具的自动化脚本:

import os
import subprocess
import json
from datetime import datetime

class PPTGenerator:
    def __init__(self):
        self.templates = {
            'marp': 'templates/marp_template.md',
            'reveal': 'templates/reveal_template.html',
            'beamer': 'templates/beamer_template.tex'
        }

    def generate_from_config(self, config_file):
        """从配置文件生成PPT"""
        with open(config_file, 'r') as f:
            config = json.load(f)

        title = config['title']
        author = config['author']
        slides = config['slides']
        output_format = config['format']

        if output_format == 'marp':
            self.generate_marp(title, author, slides)
        elif output_format == 'python-pptx':
            self.generate_python_pptx(title, author, slides)
        elif output_format == 'reveal':
            self.generate_reveal(title, author, slides)

    def generate_marp(self, title, author, slides):
        """生成Marp PPT"""
        content = f"""---
marp: true
theme: gaia
---

# {title}
**作者:** {author}
**日期:** {datetime.now().strftime('%Y-%m-%d')}

---

"""

        for slide in slides:
            content += f"# {slide['title']}\n\n"
            for point in slide['points']:
                content += f"- {point}\n"
            content += "\n---\n\n"

        with open('output.md', 'w') as f:
            f.write(content)

        # 生成PDF
        subprocess.run(['marp', 'output.md', '--pdf', '-o', 'presentation.pdf'])

    def generate_python_pptx(self, title, author, slides):
        """生成Python-pptx PPT"""
        from pptx import Presentation

        prs = Presentation()

        # 标题页
        slide = prs.slides.add_slide(prs.slide_layouts[0])
        slide.shapes.title.text = title
        slide.placeholders[1].text = f"作者:{author}"

        # 内容页
        for slide_data in slides:
            slide = prs.slides.add_slide(prs.slide_layouts[1])
            slide.shapes.title.text = slide_data['title']

            body = slide.placeholders[1].text_frame
            body.text = slide_data['points'][0]

            for point in slide_data['points'][1:]:
                p = body.add_paragraph()
                p.text = point

        prs.save('presentation.pptx')

# 使用示例
config = {
    "title": "技术分享",
    "author": "张三",
    "format": "marp",
    "slides": [
        {
            "title": "背景介绍",
            "points": ["问题描述", "目标设定", "解决方案"]
        },
        {
            "title": "技术实现",
            "points": ["架构设计", "关键技术", "实现细节"]
        }
    ]
}

generator = PPTGenerator()
generator.generate_from_config('config.json')

各种方法对比

方法 优势 劣势 适用场景
Marp 语法简单,支持多格式输出,版本控制友好 样式定制有限,复杂布局支持不足 技术分享,快速原型
Python-pptx 完全编程控制,可处理复杂逻辑,支持图表 需要编程基础,开发周期长 数据驱动PPT,批量生成
Reveal.js 丰富交互效果,Web发布,主题多样 需要Web知识,离线使用不便 在线演示,交互展示
Pandoc 格式转换灵活,支持多种输出 样式控制有限,复杂功能支持不足 文档转换,学术写作
LaTeX Beamer 专业排版,优秀的数学公式支持 学习曲线陡峭,编译较慢 学术演示,数学公式多

选择建议

根据需求选择合适的工具:

  1. 快速制作技术分享 → 选择Marp
  2. 数据驱动的商务报告 → 选择Python-pptx
  3. 在线交互演示 → 选择Reveal.js
  4. 学术论文答辩 → 选择LaTeX Beamer
  5. 批量文档转换 → 选择Pandoc

混合使用策略:

# 工作流示例
# 1. 用Markdown写内容
# 2. 用Marp生成初版
# 3. 用Python-pptx添加图表
# 4. 用Reveal.js制作在线版本

# 具体命令
marp content.md --pdf -o draft.pdf
python add_charts.py draft.pptx
pandoc content.md -t revealjs -s -o online.html

总结

脚本生成PPT的方法各有特色:

  1. 效率提升:告别重复的格式调整工作
  2. 版本控制:可以像管理代码一样管理PPT
  3. 批量处理:一次性生成多个相似的演示文稿
  4. 数据驱动:直接从数据源生成图表和内容
  5. 团队协作:多人可以同时编辑同一个演示文稿

选择哪种方法主要取决于你的具体需求、技术背景和使用场景。对于大多数技术人员来说,Marp是一个很好的起点,可以快速上手并获得不错的效果。当需要更复杂的功能时,再考虑使用Python-pptx或其他工具。


本作品由 AI 辅助创作, 采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。