跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Python

Python 将 Markdown 文件转换为 Word(docx)完整实现

Python 脚本利用 python-docx、markdown 和 BeautifulSoup 库,实现了将 Markdown 文件直接转换为 Word(docx)的功能。方案涵盖标题、段落、列表、代码块及表格的解析与映射,无需依赖外部接口。适用于技术文档迁移、自动化报告生成及后端服务集成场景,具备良好的稳定性和可扩展性。

DataScient发布于 2026/2/17更新于 2026/4/241 浏览
Python 将 Markdown 文件转换为 Word(docx)完整实现

Python 将 Markdown 文件转换为 Word(docx)完整实现

在实际开发中,经常需要将 Markdown 文档导出为 Word(.docx),比如技术文档迁移、自动生成可下载的报告,或者在 FastAPI 等后端服务里集成文档导出功能。

转换效果预览图

这里分享一个不依赖外部接口、直接读取本地 Markdown 文件并生成 Word 文件的方案。核心思路是利用 markdown 库转 HTML,再用 BeautifulSoup 解析结构,最后通过 python-docx 映射到 Word 元素。支持标题、段落、列表、代码块、表格以及加粗斜体等常见语法。

环境准备

先安装必要的依赖库:

pip install python-docx markdown beautifulsoup4

核心逻辑与代码

整体流程是:Markdown → HTML → DOM 树遍历 → Docx 对象构建。

下面是一个完整的脚本示例,包含文件读取、内容解析和保存逻辑。为了便于维护,我把处理不同元素的函数拆分开了。

from docx import Document
from docx.shared import Pt
from bs4 import BeautifulSoup
import markdown
import uuid
import os

# 输出目录配置
FILE_DIR = "static"
os.makedirs(FILE_DIR, exist_ok=True)

def md_to_word(md_text: str) -> str:
    """
    将 Markdown 文本转换为 Word,返回生成的文件名
    """
    # 1. Markdown 转 HTML,开启 extra 扩展支持更多语法
    html = markdown.markdown(
        md_text, extensions=["extra", "tables", "fenced_code"]
    )
    soup = BeautifulSoup(html, "html.parser")
    doc = Document()

    # 2. 遍历 HTML 节点,映射为 Word 元素
    for element in soup.contents:
        handle_element(doc, element)

    
    filename = 
    file_path = os.path.join(FILE_DIR, filename)
    doc.save(file_path)
     filename

 ():
    
      (el, )  el.name  :
        

    
     el.name  [, , , , , ]:
        doc.add_heading(el.get_text(), level=(el.name[]))
        

    
     el.name == :
        p = doc.add_paragraph()
        add_inline_text(p, el)
        

    
     el.name == :
         li  el.find_all(, recursive=):
            p = doc.add_paragraph(style=)
            add_inline_text(p, li)
        

    
     el.name == :
         li  el.find_all(, recursive=):
            p = doc.add_paragraph(style=)
            add_inline_text(p, li)
        

    
     el.name == :
        code_el = el.find()
        code = code_el.get_text()  code_el  el.get_text()
        p = doc.add_paragraph()
        run = p.add_run(code)
        run.font.name = 
        run.font.size = Pt()
        

    
     el.name == :
        rows = el.find_all()
        cols = rows[].find_all([, ])
        table = doc.add_table(rows=(rows), cols=(cols))
        table.style = 
         r, row  (rows):
             c, cell  (row.find_all([, ])):
                paragraph = table.rows[r].cells[c].paragraphs[]
                run = paragraph.add_run(cell.get_text())
                 cell.name == :
                    run.bold = 

 ():
    
     node  el.contents:
         (node, ):
            paragraph.add_run(node)
        :
            run = paragraph.add_run(node.get_text())
             node.name == :
                run.bold = 
             node.name == :
                run.italic = 
             node.name == :
                run.font.name = 
                run.font.size = Pt()

 () -> :
    
     (md_file_path, , encoding=)  f:
        md_text = f.read()
     md_to_word(md_text)

 __name__ == :
    md_path =   
    filename = md_to_word_from_file(md_path)
    (, filename)
# 3. 生成带 UUID 的文件名并保存
f"{uuid.uuid4().hex}.docx"
return
def
handle_element
doc, el
"""根据 HTML 标签类型调用对应的处理方法"""
if
not
hasattr
"name"
or
is
None
return
# 标题 (h1-h6)
if
in
"h1"
"h2"
"h3"
"h4"
"h5"
"h6"
int
1
return
# 段落
if
"p"
return
# 无序列表
if
"ul"
for
in
"li"
False
"List Bullet"
return
# 有序列表
if
"ol"
for
in
"li"
False
"List Number"
return
# 代码块
if
"pre"
"code"
if
else
"Courier New"
10
return
# 表格
if
"table"
"tr"
0
"th"
"td"
len
len
"Table Grid"
for
in
enumerate
for
in
enumerate
"th"
"td"
0
if
"th"
True
def
add_inline_text
paragraph, el
"""处理行内样式:加粗、斜体、行内代码"""
for
in
if
isinstance
str
else
if
"strong"
True
elif
"em"
True
elif
"code"
"Courier New"
10
def
md_to_word_from_file
md_file_path: str
str
"""从 Markdown 文件生成 Word"""
with
open
"r"
"utf-8"
as
return
if
"__main__"
"jd.md"
# 替换为你的 Markdown 文件路径
print
"生成的 Word 文件:"

运行说明

  1. 确保当前目录下有 Markdown 文件(例如 jd.md)。
  2. 运行脚本:
    python script_name.py
    
  3. 程序会在 static/ 目录下生成一个 .docx 文件,文件名由 UUID 随机生成。

后续优化方向

这个方案已经覆盖了大部分基础场景,如果项目需要更精细的控制,可以考虑以下扩展点:

  • 图片支持:目前未处理 <img> 标签,需额外编写图片下载与插入逻辑。
  • 样式增强:自定义字体、行距、页眉页脚或特定标题样式。
  • 代码高亮:引入 Pygments 等库对代码块进行着色。
  • Web 集成:封装成 FastAPI 接口,供前端触发下载。

总结

这套方案轻量、可控且易于扩展,特别适合后端服务或本地脚本使用。相比依赖在线转换 API,这种方式在数据隐私和稳定性上更有优势。如果你需要在现有系统中增加文档导出功能,可以直接在此基础上调整。

目录

  1. Python 将 Markdown 文件转换为 Word(docx)完整实现
  2. 环境准备
  3. 核心逻辑与代码
  4. 输出目录配置
  5. 运行说明
  6. 后续优化方向
  7. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • OpenClaw 入门指南:从零部署到核心原理与实操
  • Redis 与分布式架构入门:从单机到微服务的演进之路
  • Nginx 安全加固与 HTTPS 部署实战
  • 希尔排序算法详解:原理、实现与优化
  • C++ 模板初阶:从函数重载到泛型编程的优雅过渡
  • AJAX 与 Fetch:异步 Web 请求实战对比
  • 清华智谱团队:6000 亿合成交错语音文本预训练,问答性能提升近 3 倍
  • C++ 模板深度解析:实例化、重定义与隐藏依赖
  • 主流车企电子电气架构(EEA)调研分析
  • Java Lambda 与匿名内部类为何不能修改外部变量?解析 Final 与等效 Final
  • 阿里 P7 岗位能力模型解析与 Android 高级开发技术路线
  • 自动化机器学习(AutoML)实战:从原理到企业级部署
  • 用 DeepSeek 和 Cursor 从零打造智能代码审查工具
  • C++ 手撕 Sqrt 开根号算法详解与源码实现
  • QClaw 接入微信:AI 正从内容生成转向任务执行
  • AWS Kiro 账号池管理系统:OpenAI 兼容代理服务,支持多账号与 OIDC 认证
  • 2017 款 MacBook Pro 使用 WPE 重装 Windows 单系统教程
  • 阿布量化:基于 Python 的开源量化交易框架
  • OpenClaw 移动端部署实战:iOS/Android 语音唤醒与离线 AI 助手
  • Python PyQt6 实战:从零构建简易记事本

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online