关于 Word to Markdown
Word to Markdown 可通过命令行、Node.js 库、浏览器或本地 MCP 服务将 .docx 转为 Markdown,并保留表格、注释、图片和公式等结构,提供内容处理与警告选项。
主要功能
- 01将 DOCX 结构转换为 Markdown
- 02处理列表、表格和脚注
- 03将公式转换为 LaTeX
- 04内嵌或提取图片
- 05支持命令行、Node.js 和浏览器
适用场景
- 01将报告转换为 Markdown 发布
- 02在脚本中处理 DOCX 文件
- 03通过 AI Agent 转换本地文档
MCP 相关
提供本地 stdio MCP 服务,包含 `convert_docx_to_markdown` 工具,可读取并转换用户设备上的 `.docx` 文件。服务返回 Markdown 和文档警告;浏览器还提供 WebMCP 转换工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
1收录的工具列表 · 更新于 2 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | .docx 文件的路径。相对路径将相对于服务端的工作目录解析,因此建议使用绝对路径。 |
| image_dir | string | 否 | 将图像提取到此文件夹,并在 Markdown 中链接这些图像。如果设置了 output_path,则相对文件夹位于其所在文件夹内;否则位于 .docx 所在文件夹内。省略此项则丢弃图像。 |
| overwrite | boolean | 否 | 替换已存在的 output_path 或图像文件。默认关闭,因此转换不会意外覆盖文件。 |
| output_path | string | 否 | 将 Markdown 写入此 .md 文件,而不是直接返回。适用于较长的文档。 |
| bullet_lists | boolean | 否 | 将编号列表转换为项目符号列表。 |
| preserve_footnotes | boolean | 否 | 将脚注保留为原始 <sup> 链接,而不是 GFM [^1] 脚注。 |
详细介绍
Word 转 Markdown(DOCX → Markdown 转换器)
将 Word 文档转换为美观的 Markdown。可通过命令行、作为 Node 库或在浏览器中使用。原版 word-to-markdown 的更佳版本。
可在浏览器中通过 word2md.com 试用,也可以从命令行使用——无需克隆:
npx word-to-markdown input.docx > output.md
支持转换的内容
- 段落和换行
- 标题
- 粗体、斜体和删除线
- 上标和下标——保留为行内
<sup>/<sub>标签 - 项目符号列表和编号列表(默认保留为
1./2./3.) - 嵌套列表
- 表格
- 链接
- 脚注和尾注——转换为 GFM/Pandoc
[^1]脚注 - 图片——以内嵌 base64 数据 URI 的形式嵌入,或提取为文件
- 公式——转换为 LaTeX:行内公式使用
$…$,独占一行的公式使用$$块
备注和限制
- 编号列表保留为
1./2./3.有序列表,编号方式与 Word 相同,因此,如果列表被段落、表格或另一个列表打断,后续列表会从中断处继续编号。传入{ numberedLists: 'bullets' }(库)或--bullet-lists(CLI),即可将其转换为项目符号列表(与原始 word-to-markdown 的行为一致)。会重复父级编号的大纲编号(例如合同中的1.→1.1、1.2)会写成文本(## 1. Scope、1.1 Purpose),因为 Markdown 列表无法显示这种编号。 - 图片默认以内嵌的 base64 数据 URI 形式呈现。若要将图片提取为文件,并使用相对链接,请使用
{ images: 'extract' }(库——字节数据会通过ConvertResult.images返回)或--image-dir <dir>(CLI)。使用{ images: 'strip' }/--strip-images可完全移除图片。在 Web 端,包含图片的文档会提供 Download .zip(Markdown +images/文件夹)。如需完全掌控处理方式,请通过options.mammoth传入自定义的 Mammoth 图片处理程序。 - 下划线默认会被移除(这是 Mammoth 的默认行为,因为下划线很容易与链接混淆)。传入
{ underline: 'preserve' }(库)或--underline(CLI),即可将其保留为行内<u>标签。 - 弯引号(“ ” ‘ ’)在文本以中文为主时会保留,因为它们是中文引号;在其他情况下则会转换为 ASCII 字符。Word 对英文弯引号使用相同的码点,因此无法仅凭单个引号判断其类别。传入
{ quotes: 'ascii' }(库)或--quotes ascii(CLI)可始终转换为 ASCII;传入'preserve'/--quotes preserve则可始终保留。 - 脚注和尾注会转换为标准的 GFM/Pandoc 脚注——正文中使用
[^1]引用,文末使用[^1]: …定义——可在 GitHub 和 Web 预览中正常显示。传入{ footnotes: 'preserve' }(库)或--preserve-footnotes(CLI),则会改为保留 Mammoth 的原始<sup>链接和编号注释列表(适用于不支持脚注的 CommonMark 目标)。注释正文跨多个段落时,会转换为带缩进的续接段落。 - 文本框会作为段落转换,放在其所在段落之后。若文本框保存时没有 Word 的 VML 后备内容(某些其他工具会这样保存),则会被移除,并由
convertWithWarnings发出警告。 - 批注会在
.docx→ HTML 转换过程中被移除;如果有批注文本,convertWithWarnings会给出数量警告。若要保留批注,可在 Mammoth 样式映射中对其进行映射,例如{ mammoth: { styleMap: ['comment-reference => sup'] } }。 - 页眉和页脚会被移除。如果其中包含页码以外的文本,
convertWithWarnings会发出警告。 - 公式(Office Math)会转换为 LaTeX:行内公式使用
$…$,独占一行的公式使用$$…$$块,GitHub 和大多数 Markdown 数学渲染器(KaTeX、MathJax)均可显示。分数、上下标、根式、求和与积分、括号、函数与极限、重音符号和矩阵都会转换。传入{ equations: 'strip' }(库)或--strip-equations(CLI)可将其移除,并由convertWithWarnings发出警告。 - 标题级别取自 Word 的段落样式,而非字号。
这与原项目有什么不同?
TL;DR:本项目使用现代工具和库进行了彻底重写,速度更快、可靠性更高。输出效果应与原项目相同或更好。欢迎反馈!
隐私说明
Word to Markdown 将隐私作为核心原则。此应用完全在客户端运行:
- 完全在客户端处理:使用 Web 界面时,所有文档转换都通过 JavaScript 在浏览器本地完成。您的文档绝不会离开您的计算机。
- 不上传到服务器:使用 Web 界面时,文件完全在您的设备上处理。任何文档内容都不会传输到任何服务器。
- 不收集个人数据:此应用不会收集、存储或传输任何个人信息或文档内容。
- 隐私优先的分析:word2md.com 上的托管版本仅使用注重隐私的 Cloudflare Analytics 来统计匿名使用情况。不使用 Google Analytics,也不跟踪用户。
- 自托管选项:为了获得最高级别的隐私保护,您可以在本地运行此应用,或自行托管,完全不使用任何分析服务。
无论您使用命令行工具、在浏览器本地运行,还是使用托管版本,您的文档和隐私都会受到保护。
命令行
直接使用 npx 运行(下载并运行最新发布版本):
npx word-to-markdown path/to/your/file.docx > output.md
也可以全局安装,以使用 w2m 命令:
npm install -g word-to-markdown
w2m path/to/your/file.docx > output.md
转换后的 Markdown 会写入 stdout,任何文档警告(加密、敏感度标签等)都会写入 stderr,因此重定向时只会捕获 Markdown。如果文件缺失、无法读取或不是有效的 .docx 文件,命令会以状态码 1 退出,并显示友好提示。仅支持 .docx;请先将较旧的 .doc 文件重新保存为 .docx。
若要从 stdin 读取文档,请将 - 作为文件传入,或省略文件名并通过管道传入文件:
cat report.docx | w2m > report.md
curl -sL https://example.com/report.docx | w2m - -o report.md
选项:
-o, --output <file>— 将 Markdown 写入<file>,而不是 stdout(警告仍会写入 stderr)。-o -表示 stdout。--bullet-lists— 将编号列表转换为项目符号列表,而不是保留1./2./3.。--underline— 将带下划线的文本保留为行内<u>标签(默认会移除)。--strip-images— 移除图片,而不是将其嵌入为 base64 数据 URI。--image-dir <dir>— 将图片提取到<dir>并使用相对链接,而不是嵌入 base64。链接相对于 Markdown 的保存位置解析,例如:w2m --image-dir images report.docx > report.md,或使用-o:w2m -o out/report.md --image-dir images report.docx(图片会保存到out/images/)。--preserve-footnotes— 将 Word 脚注保留为原始<sup>链接和带编号的注释列表,而不是转换为 GFM[^1]脚注。--strip-equations— 移除 Word 公式,而不是将其转换为 LaTeX。--quotes <style>— 指定如何处理弯引号:auto(默认)会在以中文为主的文本中保留弯引号,ascii会在所有文本中将其转换,preserve会在所有文本中保留弯引号。-q, --quiet— 除错误外,不向 stderr 输出任何内容:不显示警告,也不显示“Wrote …”提示。--strict— 如果文档存在警告,则以状态码 2 退出,让脚本能区分“已转换,但需要检查”(2)和“转换失败”(1)。仍会写入 Markdown。与--quiet结合使用时,仅需依靠退出状态即可。--verbose— 失败时,同时打印底层错误和堆栈跟踪。-V, --version— 打印版本号。
MCP 服务
w2m mcp 会通过 stdio 在本地运行一个 Model Context Protocol 服务,让 AI Agent 转换你电脑上的 .docx 文件。和网站一样,它不会上传任何内容:Agent 会传入文件路径,服务会在本地读取并转换文件。
在 Claude Desktop 中只需点击一次:下载 word-to-markdown.mcpb,然后双击。Claude Desktop 会将其安装为扩展。你不需要 Node 或终端,因为 Claude Desktop 内置了 Node。
将其添加到 Claude Code:
claude mcp add word-to-markdown -- npx -y word-to-markdown mcp
或者添加到任何接受 JSON 配置的 MCP 客户端:
{
"mcpServers": {
"word-to-markdown": {
"command": "npx",
"args": ["-y", "word-to-markdown", "mcp"]
}
}
}
它提供一个工具 convert_docx_to_markdown:
path(必填):要转换的.docx文件。建议使用绝对路径;相对路径会相对于服务的工作目录解析。output_path:将 Markdown 写入此.md(或.markdown)文件,而不是直接返回内容,适用于较长的文档。该工具不会通过符号链接写入文件。image_dir:将图片提取到此文件夹并创建链接。它必须是output_path所在文件夹(或.docx所在文件夹)中的相对文件夹。默认情况下会丢弃图片,因为 base64 图片会占满 Agent 的上下文。overwrite:替换已存在的output_path或图片文件。默认关闭,因此文件已存在时,工具会拒绝覆盖。Agent 根据文档中读到的指示执行操作时,这一点很重要。bullet_lists、preserve_footnotes:与 CLI 标志相同。
它会返回 Markdown 和任何文档警告,也会以结构化内容的形式返回。
在浏览器中,word2md.com 会将相同的转换注册为 WebMCP 工具(convert_docx_to_markdown,接收 base64 格式的文件,以及 get_converted_markdown),供支持该功能的浏览器中的 Agent 使用。它们会在标签页中运行,就像拖放文件一样。
用作库
该库以 word-to-markdown 的名称发布到 npm。它以 ES 模块形式发布,包含 TypeScript 声明,并要求 Node 22.13 或更高版本。
npm install word-to-markdown
import convert, { convertWithWarnings } from 'word-to-markdown';
// Just the Markdown:
const markdown = await convert('path/to/your/file.docx');
// Markdown plus any document warnings (e.g. encryption, sensitivity labels):
const { markdown, warnings } = await convertWithWarnings(
'path/to/your/file.docx',
);
两个函数都接受文件路径字符串(Node)或 ArrayBuffer(Node 或浏览器):
const { markdown } = await convertWithWarnings(arrayBuffer);
API
convert(input, options?): Promise<string>— 解析为 Markdown。convertWithWarnings(input, options?): Promise<{ markdown: string; warnings: string[]; warningDetails: WarningDetail[]; images? }>— 还会返回关于加密、受保护或带有敏感性标签的文档,以及被丢弃内容的易读警告;在extract模式下也会返回提取的图片。每条警告对应warningDetails中的一个{ kind, message, detail? }条目,其中kind为encrypted、sensitivity、confidentiality、protected或content-loss,detail为文档标签或 Mammoth 的原始消息。可用它来呈现或翻译警告,而无需解析英文文本。convertHtml(html, options?): Promise<string>— 转换 HTML 字符串,例如从 Word、Google Docs 或网页复制的富文本,并进行相同的清理。由于没有.docx,mammoth、images: 'extract'和imageDir不适用。
input 是文件路径 string(Node)或 ArrayBuffer。options(类型为 ConvertOptions)为可选参数:
images—'inline'(默认)将图片嵌入为 base64 数据 URI;'strip'会移除图片;'extract'会将每张图片替换为相对链接,并将字节数据作为ConvertResult.images返回(使用convertWithWarnings获取)。imageDir— 提取图片的链接/路径前缀(默认'images');仅适用于images: 'extract'。numberedLists—'ordered'(默认)保留1./2./3.;'bullets'会将编号列表转换为项目符号列表。underline—'ignore'(默认)丢弃下划线;'preserve'会将其保留为行内<u>标签。footnotes—'gfm'(默认)将脚注和尾注转换为[^1]引用和定义;'preserve'会保留 Mammoth 的原始<sup>链接和编号注释列表。equations—'latex'(默认)将 Word 公式转换为$…$/$$…$$LaTeX;'strip'会丢弃公式。quotes—'auto'(默认)在文本以中文为主时保留中文引号,否则将弯引号转换为 ASCII 引号;'ascii'始终转换;'preserve'始终保留。mammoth/turndown— 分别传递给 Mammoth 和 Turndown 的逃生选项。
// Extract images to files and write them out yourself:
const { markdown, images } = await convertWithWarnings('file.docx', {
images: 'extract',
});
// markdown → ; images → [{ path, contentType, bytes }]
错误处理
转换会抛出带类型的错误,让你能针对每种故障进行精确处理。它们都继承自 WordToMarkdownError,因此 error instanceof WordToMarkdownError 可以捕获其中任意一种错误。
import convert, {
UnsupportedFileError,
FileNotFoundError,
InvalidFileError,
FilePermissionError,
DocumentTooLargeError,
ConversionError,
} from 'word-to-markdown';
try {
const markdown = await convert('path/to/your/file.docx');
} catch (error) {
if (error instanceof UnsupportedFileError) {
// a .doc or password-protected file — only unprotected .docx is supported
} else if (error instanceof FileNotFoundError) {
// the path doesn't exist (or runs through something that isn't a directory)
} else if (error instanceof InvalidFileError) {
// not a valid or parseable .docx (or the path is a directory)
} else if (error instanceof FilePermissionError) {
// the file couldn't be read, or is in a blocked system directory
} else if (error instanceof DocumentTooLargeError) {
// unpacks to more than 200 MB (a zip bomb, or too big to convert in memory)
} else if (error instanceof ConversionError) {
// something failed mid-conversion — see error.cause
}
}
本地运行
准备环境
- 克隆代码仓库
- 运行
npm install
命令行(从源代码运行)
先运行一次 npm run build:js,然后运行 node build/cli.js path/to/your/file.docx。
本地运行网站
npm run dev 会启动 Astro 开发服务器。要预览生产构建,请运行 npm run build,然后运行 npm run preview。
自托管
使用 Docker Compose 自托管静态网站:
- 克隆代码仓库
- 运行
npm install && npm run build - 运行
docker compose up -d - 访问 http://localhost:3000
此方式使用纯 nginx 提供 dist/,因此不会包含 Cloudflare Worker 和 public/_headers 在生产环境中添加的功能:/ 上的 Accept-Language 重定向、/api/event 计数器(对其发出的请求会返回 404)、安全标头,以及 /_astro/* 的长期缓存。转换本身在浏览器中运行,效果相同。要在本地搭建近似生产环境的配置,请运行 npm run build,然后运行 npx wrangler dev。
更多背景信息
有关项目的动机,请参阅 原始 Word to Markdown 项目的 README。
旧方法
原版 Word to Markdown 已有 10 年历史。转换过程如下:
- 使用 LibreOffice 将 Word 文档转换为 HTML。
- 使用大量正则表达式清理 HTML
- 使用 Premailer 将 CSS 内联
- 使用 Nokogiri 进一步处理 HTML
- 使用 Reverse Markdown 将 HTML 转换为 Markdown
- 使用大量正则表达式清理 Markdown
这个过程不仅需要安装并调用体积庞大的二进制程序(LibreOffice),而且非常脆弱;Reverse Markdown 等关键项目也已停止维护。我尝试过使用 Pandoc,但它也存在许多相同的局限。
新方法
- 使用 Mammoth.js 将 Word 文档转换为 HTML。
- 使用 domino(Turndown 用来解析的 DOM)清理 HTML(展开代码块表格、扩展合并的表格单元格、添加表头行、移除字面项目符号)。
- 使用 Turndown 将 HTML 转换为 Markdown。
- 使用 Markdownlint 清理 Markdown。
- 使用 Prettier 统一格式。
所有这些项目都在积极维护,并被广泛使用;借助它们,我们可以完全使用 JavaScript 更快地转换文档。这也意味着它可以在浏览器中运行:word2md.com 会在你的设备上转换文档,不会将文档上传到任何地方。
虽然这个项目还很新,但到目前为止,我发现它的输出质量更好,需要的手动清理也少得多。发现哪里不对?请提交问题。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。