Python 实现 Markdown 转 Word(markdown+python-docx 方案)
一、核心方案说明
要实现 Markdown 文件 → Word(.docx) 文件 的格式转换,核心思路是:
✅ 先用 python-markdown 库把 Markdown 文本/文件解析成 HTML 格式;
✅ 再用 python-docx 库将解析后的 HTML 内容,逐节点渲染到 Word 文档中,完成最终转换。
二、完整环境安装(一键执行)
该方案依赖 3 个核心库,直接在终端执行以下命令安装所有依赖:
pip install python-markdown python-docx beautifulsoup4
python-markdown:核心 Markdown 解析库,负责 MD → HTML;python-docx:核心 Word 操作库,负责生成/编辑 .docx 文档;beautifulsoup4:辅助解析 HTML 节点,方便精准提取内容渲染到 Word。
三、完整可运行代码(直接复用)
版本 1:基础版(支持绝大多数 MD 语法,满足日常需求)
支持标题(1-6 级)、段落、加粗、斜体、有序列表、无序列表、超链接、图片、换行等核心语法,代码可直接复制运行:
import markdown
from docx import Document
from docx.shared import Pt, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
from bs4 import BeautifulSoup
import os
def markdown_to_word(md_file_path, docx_file_path=None):
""" Markdown 文件转 Word 文档核心函数
:param md_file_path: 源 Markdown 文件路径(必填,如:./test.md)
:param docx_file_path: 输出 Word 文件路径(可选,默认同目录同名.docx)
"""
# 1. 校验源文件是否存在
if not os.path.exists(md_file_path):
print(f"错误:源文件 {md_file_path} 不存在!")
return
# 2. 默认输出路径(同目录、同名,后缀替换为.docx)
docx_file_path :
docx_file_path = os.path.splitext(md_file_path)[]+
(md_file_path,, encoding=) f:
md_content = f.read()
html_content = markdown.markdown(
md_content,
extensions=[, , ],
extension_configs={}
)
doc = Document()
doc.styles[].font.name =
doc.styles[]._element.rPr.rFonts.(qn(),)
doc.styles[].font.size = Pt()
soup = BeautifulSoup(html_content,)
parse_html_node(soup, doc)
doc.save(docx_file_path)
()
():
node.name [ i (,)]:
level = (node.name[])
p = doc.add_paragraph()
run = p.add_run(node.get_text(strip=))
run.font.size = Pt(- level *)
run.font.bold =
run.font.name =
run._element.rPr.rFonts.(qn(),)
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
node.name == :
p = doc.add_paragraph()
parse_inline_content(node, p)
node.name == :
li node.find_all(, recursive=):
p = doc.add_paragraph(style=)
parse_inline_content(li, p)
node.name == :
li node.find_all(, recursive=):
p = doc.add_paragraph(style=)
parse_inline_content(li, p)
node.name == :
doc.add_paragraph()
child node.children:
child.name:
parse_html_node(child, doc)
():
content node.contents:
(content,):
run = paragraph.add_run(content)
run.font.name =
run._element.rPr.rFonts.(qn(),)
run.font.size = Pt()
content.name == :
run = paragraph.add_run(content.get_text())
run.font.bold =
run.font.name =
run._element.rPr.rFonts.(qn(),)
content.name == :
run = paragraph.add_run(content.get_text())
run.font.italic =
run.font.name =
run._element.rPr.rFonts.(qn(),)
content.name == :
text = content.get_text()
link = content.get(,)
run = paragraph.add_run()
run.font.color.rgb =
run.font.name =
run._element.rPr.rFonts.(qn(),)
__name__ == :
INPUT_MD_FILE =
OUTPUT_DOCX_FILE =
markdown_to_word(INPUT_MD_FILE, OUTPUT_DOCX_FILE)

