【原创实践】Python 将 Markdown 文件转换为 Word(docx)完整实现
Python 将 Markdown 文件转换为 Word(docx)完整实现
在实际开发中,经常会遇到将 Markdown 文档转换为 Word(.docx)的需求,例如:
- 技术文档从 Markdown 迁移到 Word
- 自动生成可下载的 Word 报告
与 Dify、FastAPI 等系统结合做文档导出

本文基于 python-docx + markdown + BeautifulSoup,实现一个不依赖接口、直接读取 Markdown 文件并生成 Word 文件的完整方案,支持常见 Markdown 语法。
参考链接 https://mp.weixin.qq.com/s/vyz5d9Hya9UEEEvOiro9Vg
一、实现思路说明
整体转换流程如下:
- 使用
markdown库将 Markdown 文本转换为 HTML - 使用
BeautifulSoup解析 HTML 结构 - 遍历 HTML 节点,映射为 Word 中的对应元素
- 使用
python-docx生成并保存.docx文件
支持的 Markdown 元素包括:
- 标题(h1–h6)
- 段落
- 无序 / 有序列表
- 代码块
- 行内代码、加粗、斜体
- 表格
二、依赖安装
pip install python-docx markdown beautifulsoup4 三、完整代码实现
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)defmd_to_word(md_text:str)->str:""" 将 Markdown 文本转换为 Word,返回生成的文件名 """ html = markdown.markdown( md_text, extensions=["extra","tables","fenced_code"]) soup = BeautifulSoup(html,"html.parser") doc = Document()for element in soup.contents: handle_element(doc, element) filename =f"{uuid.uuid4().hex}.docx" file_path = os.path.join(FILE_DIR, filename) doc.save(file_path)return filename defhandle_element(doc, el):ifnothasattr(el,"name")or el.name isNone:return# 标题if el.name in["h1","h2","h3","h4","h5","h6"]: doc.add_heading(el.get_text(), level=int(el.name[1]))return# 段落if el.name =="p": p = doc.add_paragraph() add_inline_text(p, el)return# 无序列表if el.name =="ul":for li in el.find_all("li", recursive=False): p = doc.add_paragraph(style="List Bullet") add_inline_text(p, li)return# 有序列表if el.name =="ol":for li in el.find_all("li", recursive=False): p = doc.add_paragraph(style="List Number") add_inline_text(p, li)return# 代码块if el.name =="pre": code_el = el.find("code") code = code_el.get_text()if code_el else el.get_text() p = doc.add_paragraph() run = p.add_run(code) run.font.name ="Courier New" run.font.size = Pt(10)return# 表格if el.name =="table": rows = el.find_all("tr") cols = rows[0].find_all(["th","td"]) table = doc.add_table(rows=len(rows), cols=len(cols)) table.style ="Table Grid"for r, row inenumerate(rows):for c, cell inenumerate(row.find_all(["th","td"])): paragraph = table.rows[r].cells[c].paragraphs[0] run = paragraph.add_run(cell.get_text())if cell.name =="th": run.bold =Truedefadd_inline_text(paragraph, el):""" 处理行内样式:加粗、斜体、行内代码 """for node in el.contents:ifisinstance(node,str): paragraph.add_run(node)else: run = paragraph.add_run(node.get_text())if node.name =="strong": run.bold =Trueelif node.name =="em": run.italic =Trueelif node.name =="code": run.font.name ="Courier New" run.font.size = Pt(10)defmd_to_word_from_file(md_file_path:str)->str:""" 从 Markdown 文件生成 Word """withopen(md_file_path,"r", encoding="utf-8")as f: md_text = f.read()return md_to_word(md_text)if __name__ =="__main__": md_path ="jd.md"# Markdown 文件路径 filename = md_to_word_from_file(md_path)print("生成的 Word 文件:", filename)四、使用说明
- 将 Markdown 文件(如
jd.md)放到当前目录 - 运行脚本:
python md_to_word.py - 程序会在
static/目录下生成一个.docx文件,文件名为 UUID
五、适用场景
- FastAPI / Flask 文档导出
- Dify 工作流中生成 Word 报告
- Markdown 文档批量转 Word
- 内部系统自动生成可编辑文档
六、可优化方向
- 增加图片(
img)支持 - 支持代码高亮样式
- 表格列宽自适应
- 自定义标题样式、字体、行距
- 与 FastAPI 接口结合返回下载地址
七、总结
本文实现了一个轻量、可控、易扩展的 Markdown 转 Word 方案,不依赖外部接口,适合后端服务或本地脚本使用。
对于需要文档导出、报告生成的场景,这种方式在稳定性和可维护性上都具有明显优势。
如果你后续需要 FastAPI 接口版、Dify 工作流集成版 或 样式增强版,可以在此基础上直接扩展。