python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python Markdown与Word互转

Python实现Markdown与Word(DOC/DOCX)文档格式互转

作者:缺点内向

在日常开发与文档处理中,Markdown 与 Word 是两种定位截然不同的格式,本文将以 Spire.Doc for Python 为例,介绍 Markdown 与 Word(DOC/DOCX)互转的实现方式,有需要的小伙伴可以了解下

在日常开发与文档处理中,Markdown 与 Word 是两种定位截然不同的格式。Markdown 以纯文本为基础,结构轻量、便于版本管理,适合技术文档、笔记和静态站点内容;Word 则凭借成熟的排版能力和审阅功能,在企业环境与正式交付场景中依然不可替代。当同一份内容需要在两种场景间流转时,格式转换便成了一个绕不开的环节。

手动复制粘贴不仅效率低下,还容易丢失标题层级、列表结构和表格格式。借助 Python 文档处理库,可以将这一过程自动化。本文以 Spire.Doc for Python 为例,介绍 Markdown 与 Word(DOC/DOCX)互转的实现方式,并讨论转换中需要注意的实际问题。

环境准备

Spire.Doc for Python 通过 pip 即可安装,无需依赖本地安装的 Microsoft Word 或其他办公软件。

在脚本中导入所需模块:

from spire.doc import *
from spire.doc.common import *

该库从 12.6.0 版本开始支持 Markdown 文档的加载与保存。如果使用较早版本,Markdown 相关功能可能不可用。

Markdown 转 Word

将 Markdown 转换为 Word 的核心逻辑只有两步:加载源文件时指定格式为 FileFormat.Markdown,保存时指定目标格式为 FileFormat.Docx 或 FileFormat.Doc。

from spire.doc import *
from spire.doc.common import *

document = Document()
document.LoadFromFile("input.md", FileFormat.Markdown)

# 输出为 DOCX
document.SaveToFile("output.docx", FileFormat.Docx)

# 如需旧版 DOC 格式
# document.SaveToFile("output.doc", FileFormat.Doc)

document.Close()

代码中 LoadFromFile 的第二个参数显式声明了源文件格式。虽然对于 .md 后缀,库也能自动识别,但显式指定可以避免歧义。转换后的 Word 文档会保留 Markdown 中的标题层级、列表、表格等基础结构,但 Word 的复杂排版能力(如页眉页脚、多栏布局)在 Markdown 中本就不存在,因此输出结果以内容结构清晰为主,而非精细排版。

Word 转 Markdown

反向转换的代码结构完全对称。加载 Word 文件时无需额外指定格式(.doc 和 .docx 均可自动识别),保存时使用 FileFormat.Markdown。

document = Document()
document.LoadFromFile("input.docx")

document.SaveToFile("output.md", FileFormat.Markdown)
document.Close()

Word 中的各级标题会映射为 Markdown 的 # 到 ###### 标签,段落保留换行,有序与无序列表被正确识别,表格也会转换为 Markdown 表格语法。对于以文字内容为主的文档,这一转换过程基本可以保留核心信息。

图片处理:一个容易被忽视的问题

Word 转 Markdown 时,图片的处理方式值得特别留意。默认情况下,Spire.Doc 会将文档中嵌入的图片以 Base64 编码形式直接写入 Markdown 文件。这种做法的优点是单文件自包含,分享时不会丢失图片;但缺点同样明显:当文档包含多张高清图片时,生成的 .md 文件体积会急剧膨胀,可能达到数十甚至上百 MB,导致编辑器卡顿,也不利于放入 Git 等版本控制系统。

一种可行的缓解方式是在转换前先提取图片到独立目录,再以相对路径引用的方式写入 Markdown。该库提供了 document.Images 集合用于遍历图片数据。不过需要注意的是,SaveToFile 方法本身并不提供“保存时自动外链图片”的参数,提取后仍需对生成的 Markdown 内容做后处理,将 Base64 图片块替换为 ![](images/img_x.png) 形式的引用。如果转换任务频繁且图片较多,建议将这一步骤纳入脚本流程,而非依赖手动操作。

另一种更简单的策略是在转换前移除图片。如果 Markdown 产物主要用于文本检索或语料准备,图片并非必需,跳过图片可以显著减小文件体积并提升转换速度。

实际转换中的局限与应对

格式转换并非无损。Markdown 的语法表达能力有限,Word 中的若干元素在转换后可能丢失或降级:

因此,在批量转换之前,建议先用一份有代表性的文档做试转换,确认关键内容(标题层级、代码块、表格数据)的保留情况。由于输出是纯文本,也可以编写简单的校验脚本,检查文件是否为空、标题层级是否正确、关键段落是否存在,这比逐个人工核对更为可靠。

对于需要批量处理的场景,将单文件转换逻辑封装为函数后,配合 os.listdir 遍历目录即可:

import os

input_folder = "docs"
output_folder = "markdown_output"

for filename in os.listdir(input_folder):
    if filename.lower().endswith(".docx"):
        doc = Document()
        doc.LoadFromFile(os.path.join(input_folder, filename))
        md_name = os.path.splitext(filename)[0] + ".md"
        doc.SaveToFile(os.path.join(output_folder, md_name), FileFormat.Markdown)
        doc.Close()

在 Windows 环境下,如果目标目录中的文档曾被 Word 打开过,可能会产生以 ~$ 开头的临时文件,遍历时需要注意过滤。

适用场景与选择建议

Markdown 转 Word 的典型场景包括:用 Markdown 完成内容撰写后,需要以正式格式交付给非技术同事或客户;将静态站点中的文档导出为可打印的 Word 版本。反过来,Word 转 Markdown 则常见于存量文档迁移——将历史 Word 手册批量转为 Markdown 后接入文档站点或知识库,或者为文本检索、大模型语料准备纯文本数据。

需要明确的是,这类转换工具提供的能力侧重于内容结构的迁移,而非版式的精确复刻。如果需求是保留 Word 文档的每一处排版细节并输出 PDF,那属于另一类任务(该库也支持 Word 转 PDF),与 Markdown 互转的目标并不相同。理解这一点,有助于在合适的场景中使用合适的工具,避免对转换结果产生不切实际的预期。

知识扩展

Markdown 与 Word 的互转,Python 里有两条清晰的路径:通用转换用 pypandoc(底层是 Pandoc),Word 转 Markdown 用 mammoth(语义化转换) 。两条路径各有明确的适用边界,不能互相替代。

先装工具:两套核心库

路径一:pypandoc(双向通用,依赖 Pandoc)

pypandoc 本身只是一个 Python 封装,真正的转换引擎是 Pandoc。有两种安装方式:

# 方式一:包含预编译 Pandoc 二进制,开箱即用(推荐)
pip install pypandoc_binary
# 方式二:自行安装 Pandoc 后,再装轻量封装
pip install pypandoc
# 然后手动安装 Pandoc(macOS: brew install pandoc;Ubuntu: sudo apt install pandoc)

pypandoc_binary 省去了单独安装 Pandoc 的步骤,适合不想折腾系统依赖的场景。但如果你的转换需求涉及模板、复杂表格等高级特性,自行安装最新版 Pandoc 配合 pypandoc 会更灵活。

路径二:mammoth(Word → Markdown,纯 Python)

pip install mammoth

mammoth 不依赖任何外部二进制,安装即用。它的设计哲学是提取 Word 文档的语义结构,而不是逐像素复制样式——把 “Heading 1” 转成 <h1>,把表格转成结构化数据,忽略字体、颜色、缩进等视觉细节。这恰好是 Markdown 需要的。

Markdown → Word:pypandoc 是主线

1.基础转换(一行代码)

import pypandoc

# 从文件转换
pypandoc.convert_file("input.md", "docx", outputfile="output.docx")

# 从字符串转换
pypandoc.convert_text("# 标题\n\n正文内容 **加粗**。", "docx", format="md", outputfile="output.docx")

convert_file 和 convert_text 是 pypandoc 最核心的两个入口。format="md" 明确告诉 Pandoc 输入格式是 Markdown;outputfile 参数是必需的,因为 Pandoc 在转换为 docx 这类二进制格式时,只能写入文件,不能直接返回字符串。

2.使用 Word 模板控制样式

直接转换生成的 Word 文档使用的是 Pandoc 的默认样式(字体、字号、页边距)。如果需要匹配公司或机构的格式规范,可以用 --reference-doc 指定一个样式模板:

pypandoc.convert_file(
    "input.md", "docx",
    outputfile="output.docx",
    extra_args=["--reference-doc", "template.docx"]
)

template.docx 不需要包含任何内容,只需要在其中预设好标题、正文、列表等样式定义。Pandoc 会读取这些样式,并套用到转换后的内容上。

3.处理数学公式

Pandoc 原生支持将 Markdown 中的 LaTeX 公式($...$ 和 $$...$$)转换为 Word 原生可编辑的公式对象:

pypandoc.convert_text(
    "质能方程:$E = mc^2$", "docx",
    format="md", outputfile="equation.docx"
)

转换后,Word 中显示的是真正的公式对象,双击即可编辑,而非图片。

4.纯 Python 方案(不依赖 Pandoc)

如果环境限制无法安装 Pandoc,md-to-office 是一个值得考虑的替代品:只输出 Word 时,依赖仅 python-docx + Pillow,支持中文字体、标题层级、表格、图片,并内置了面向中文公文和报告的排版预设。它的定位更偏向“中文交付物生成”,而非通用文档转换,如果你的场景恰好匹配,它会比 Pandoc 更轻量。

Word → Markdown:mammoth 做语义转换

1.核心用法:DOCX → HTML → Markdown

mammoth 直接输出 Markdown 的支持已被标记为 deprecated,官方推荐的做法是先转 HTML,再用 markdownify 将 HTML 转为 Markdown,这样结果更干净、可控:

import mammoth
from markdownify import markdownify

with open("document.docx", "rb") as f:
    result = mammoth.convert_to_html(f)

markdown_text = markdownify(result.value, heading_style="ATX")  # ATX 即 # 风格标题

with open("output.md", "w", encoding="utf-8") as f:
    f.write(markdown_text)

mammoth.convert_to_html 返回一个结果对象,.value 是 HTML 字符串,.messages 包含转换过程中的警告(例如无法映射的样式)。HTML 阶段可以先用 BeautifulSoup 做清洗,再交给 markdownify,控制粒度更细。

2.保留表格与图片

mammoth 原生支持表格转换为 HTML 的 <table>,markdownify 会将其进一步转为 Markdown 管道表格。图片的处理需要额外指定输出目录:

with open("document.docx", "rb") as f:
    result = mammoth.convert_to_html(f, convert_image=mammoth.images.img_element)

如果要将图片提取为独立文件并在 Markdown 中引用,使用 --output-dir 风格的处理:

import mammoth, os
from markdownify import markdownify

os.makedirs("images", exist_ok=True)

def save_image(image):
    with image.open() as img:
        ext = image.content_type.split("/")[-1]
        filename = f"images/{image.alt_text or 'img'}.{ext}"
        with open(filename, "wb") as out:
            out.write(img.read())
    return {"src": filename}

with open("document.docx", "rb") as f:
    result = mammoth.convert_to_html(f, convert_image=save_image)

md = markdownify(result.value)

这样图片会被保存到 images/ 目录,Markdown 中生成 ![](images/xxx.png) 形式的引用,文件结构清晰、可移植。

3.更直接的封装:docx2md / MarkItDown

如果不想手动串联 mammoth + markdownify,有两个现成的上层封装:

docx2md(来自 ez 包)提供一行式 API:

import ez
markdown = ez.docx2md("report.docx", images=True, output="report.md")

支持标题、列表、表格、链接的转换,images=True 会将图片嵌入为 base64 或保存为文件。

MarkItDown(微软出品)内部使用 mammoth 做 DOCX → HTML → Markdown 的管道,对外暴露统一的 convert 接口,适合需要同时处理多种格式(PDF、PPTX、XLSX)的场景。

到此这篇关于Python实现Markdown与Word(DOC/DOCX)文档格式互转的文章就介绍到这了,更多相关Python Markdown与Word互转内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文