一、Mammoth.js 是什么?
Mammoth.js 是一个开源的 JavaScript 库,专门用于将 Microsoft Word 文档(.docx 格式)转换为 HTML、Markdown 或纯文本。它的核心优势是尽可能保留原文档的格式和结构,且支持浏览器端和 Node.js 服务端两种运行环境,是处理 docx 文档转换的首选工具。
核心特点
- 支持 docx → HTML/Markdown/纯文本 转换
- 自动处理段落、列表、表格、图片、样式等
- 轻量且无强依赖
- 浏览器和 Node.js 双端兼容
二、环境准备
1. 安装 Mammoth.js
根据你的运行环境选择对应的安装方式:
(1)Node.js 环境(服务端)
# 使用 npm 安装
npm install mammoth --save
# 或使用 yarn 安装
yarn add mammoth
(2)浏览器环境(客户端)
可以通过 CDN 引入,或下载源码到本地:
<!-- 通过 CDN 引入 -->
<script src="https://unpkg.com/mammoth@1.6.0/mammoth.browser.min.js"></script>
<!-- 本地引入(需先下载 mammoth.browser.min.js) -->
<script src="./mammoth.browser.min.js"></script>
2. 环境要求
- Node.js:v10+(推荐 v14+)
- 浏览器:支持 ES6 的现代浏览器(Chrome、Firefox、Edge 等)
三、基础使用
1. Node.js 环境下的基础用法
(1)将 docx 文件转换为 HTML
创建 convert-docx-to-html.js 文件:
// 引入 fs 模块(用于读取文件)和 mammoth 模块
const fs = require('fs');
const mammoth = require('mammoth');
// 定义转换函数
async function convertDocxToHtml(filePath) {
try {
// 读取 docx 文件(二进制格式)
const buffer = fs.readFileSync(filePath);
// 核心转换方法:convertToHtml
const result = await mammoth.convertToHtml({ buffer: buffer });
// 转换后的 HTML 内容
const html = result.value;
// 转换过程中的警告信息(如不支持的格式)
const warnings = result.warnings;
// 输出结果
console.log('转换后的 HTML:');
console.log(html);
if (warnings.length > 0) {
console.log('\n转换警告:');
warnings.forEach(warning => console.log(warning.message));
}
// 将 HTML 保存到文件
fs.writeFileSync('output.html', html);
console.log('\nHTML 文件已保存到 output.html');
} catch (error) {
console.error('转换失败:', error.message);
}
}
// 调用函数(替换为你的 docx 文件路径)
convertDocxToHtml('./test.docx');
运行方式:
node convert-docx-to-html.js
(2)转换为纯文本
const fs = require('fs');
const mammoth = require('mammoth');
async function convertDocxToText(filePath) {
try {
const buffer = fs.readFileSync(filePath);
// 转换为纯文本
const result = await mammoth.extractRawText({ buffer: buffer });
const text = result.value;
console.log('转换后的纯文本:');
console.log(text);
// 保存纯文本
fs.writeFileSync('output.txt', text);
} catch (error) {
console.error('转换失败:', error.message);
}
}
convertDocxToHtml('./test.docx');
2. 浏览器环境下的基础用法
通过文件上传控件实现前端 docx 转 HTML:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Mammoth.js 浏览器端示例</title>
<!-- 引入 Mammoth.js -->
<script src="https://unpkg.com/mammoth@1.6.0/mammoth.browser.min.js"></script>
</head>
<body>
<h1>Docx 转 HTML</h1>
<!-- 文件上传控件 -->
<input type="file" id="docxFile" accept=".docx">
<!-- 显示转换结果 -->
<div style="margin-top: 20px;">
<h3>转换结果:</h3>
<div id="output" style="border: 1px solid #ccc; padding: 10px; min-height: 200px;"></div>
</div>
<script>
// 获取 DOM 元素
const fileInput = document.getElementById('docxFile');
const outputDiv = document.getElementById('output');
// 监听文件选择事件
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
if (!file) return;
// 验证文件格式
if (file.type !== 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
alert('请选择 .docx 格式的 Word 文档!');
return;
}
try {
outputDiv.innerHTML = '正在转换...';
// 读取文件为 ArrayBuffer
const reader = new FileReader();
reader.onload = async (event) => {
const arrayBuffer = event.target.result;
// 转换为 HTML
const result = await mammoth.convertToHtml({ arrayBuffer: arrayBuffer });
const html = result.value;
const warnings = result.warnings;
// 显示 HTML 结果
outputDiv.innerHTML = html;
// 显示警告信息
if (warnings.length > 0) {
const warningsHtml = `<div style="color: #ff6347; margin-top: 10px;">
<strong>转换警告:</strong><br>
${warnings.map(w => w.message).join('<br>')}
</div>`;
outputDiv.insertAdjacentHTML('afterend', warningsHtml);
}
};
reader.readAsArrayBuffer(file);
} catch (error) {
outputDiv.innerHTML = `<span style="color: red;">转换失败:${error.message}</span>`;
}
});
</script>
</body>
</html>
四、高级用法
1. 自定义样式映射
Mammoth.js 允许你将 Word 中的样式(如标题、段落)映射到自定义的 HTML 标签/类名,实现更精准的格式控制:
const mammoth = require('mammoth');
const fs = require('fs');
async function convertWithCustomStyles(filePath) {
const buffer = fs.readFileSync(filePath);
// 自定义样式映射规则
const styleMap = [
// Word 中的 "标题 1" 映射为 <h1 class="title-1">
"p[style-name='标题 1'] => h1.title-1:fresh",
// Word 中的 "标题 2" 映射为 <h2 class="title-2">
"p[style-name='标题 2'] => h2.title-2:fresh",
// Word 中的 "正文" 映射为 <p class="content">
"p[style-name='正文'] => p.content:fresh",
// 无序列表项映射为 <li class="unordered-list">
"ul/li => li.unordered-list:fresh"
];
const result = await mammoth.convertToHtml({ buffer: buffer }, {
styleMap: styleMap, // 应用样式映射
includeEmbeddedImages: true // 包含嵌入式图片
});
fs.writeFileSync('custom-output.html', result.value);
console.log('自定义样式转换完成!');
}
convertWithCustomStyles('./test.docx');
2. 处理图片
Mammoth.js 支持提取 docx 中的嵌入式图片,并转换为 HTML 的 img 标签(Base64 格式):
const mammoth = require('mammoth');
const fs = require('fs');
async function convertWithImages(filePath) {
const buffer = fs.readFileSync(filePath);
const result = await mammoth.convertToHtml({ buffer: buffer }, {
// 启用图片处理
includeEmbeddedImages: true,
// 自定义图片转换逻辑(可选)
convertImage: mammoth.images.imgElement(function(image) {
// image 包含:contentType(图片类型)、buffer(图片二进制)
return image.read("base64").then(function(base64) {
return {
src: `data:${image.contentType};base64,${base64}`,
alt: "文档图片",
style: "max-width: 100%; height: auto;" // 自适应样式
};
});
})
});
fs.writeFileSync('with-images.html', result.value);
console.log('包含图片的 HTML 已生成!');
}
convertWithImages('./test-with-images.docx');
3. 转换为 Markdown
Mammoth.js 也支持将 docx 转换为 Markdown 格式(需注意:Markdown 转换的格式支持度略低于 HTML):
const mammoth = require('mammoth');
const fs = require('fs');
async function convertToMarkdown(filePath) {
const buffer = fs.readFileSync(filePath);
// 先转换为 HTML,再通过第三方库(如 turndown)转 Markdown
// 注:Mammoth 原生不直接支持 Markdown,需借助中间转换
const htmlResult = await mammoth.convertToHtml({ buffer: buffer });
const html = htmlResult.value;
// 安装 turndown:npm install turndown
const TurndownService = require('turndown');
const turndownService = new TurndownService();
const markdown = turndownService.turndown(html);
fs.writeFileSync('output.md', markdown);
console.log('Markdown 文件已生成!');
}
convertToMarkdown('./test.docx');
五、常见问题与解决方案
1. 转换后格式错乱
-
原因:Word 中的复杂样式(如自定义样式、嵌套表格)未被正确映射
-
解决方案:
- 使用
styleMap自定义样式映射规则 - 简化 Word 文档中的复杂格式,优先使用内置样式(标题 1/2/3、正文等)
- 使用
2. 图片无法显示
-
原因:未启用
includeEmbeddedImages配置,或图片格式不支持 -
解决方案:
- 确保配置
includeEmbeddedImages: true - 检查图片格式(Mammoth 支持 jpg/png/gif 等主流格式)
- 确保配置
3. 浏览器端跨域/文件大小限制
-
原因:浏览器对 FileReader 读取大文件有限制,或跨域资源问题
-
解决方案:
- 限制上传文件大小(建议不超过 10MB)
- 大文件建议通过服务端转换
4. 不支持 .doc 格式
- 原因:Mammoth.js 仅支持 .docx(Office 2007+),不支持旧版 .doc 格式
- 解决方案:将 .doc 转换为 .docx 后再处理
六、完整示例(服务端 + 前端)
1. 服务端(Express)
// server.js
const express = require('express');
const mammoth = require('mammoth');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const app = express();
const upload = multer({ dest: 'uploads/' }); // 临时上传目录
// 静态文件托管
app.use(express.static('public'));
// 转换接口
app.post('/convert', upload.single('docxFile'), async (req, res) => {
try {
const filePath = req.file.path;
const buffer = fs.readFileSync(filePath);
// 转换为 HTML
const result = await mammoth.convertToHtml({ buffer: buffer }, {
includeEmbeddedImages: true
});
// 删除临时文件
fs.unlinkSync(filePath);
res.json({
success: true,
html: result.value,
warnings: result.warnings
});
} catch (error) {
res.json({
success: false,
message: error.message
});
}
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});
2. 前端页面(public/index.html)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Docx 转换工具</title>
</head>
<body>
<h1>Docx 转 HTML 工具</h1>
<form id="convertForm">
<input type="file" name="docxFile" accept=".docx" required>
<button type="submit">转换</button>
</form>
<div id="result" style="margin-top: 20px; border: 1px solid #ccc; padding: 10px; min-height: 300px;"></div>
<script>
const form = document.getElementById('convertForm');
const resultDiv = document.getElementById('result');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(form);
resultDiv.innerHTML = '正在转换...';
try {
const response = await fetch('/convert', {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.success) {
resultDiv.innerHTML = data.html;
if (data.warnings.length > 0) {
const warnings = `<div style="color: orange; margin-top: 10px;">
警告:${data.warnings.map(w => w.message).join('; ')}
</div>`;
resultDiv.insertAdjacentHTML('afterend', warnings);
}
} else {
resultDiv.innerHTML = `<span style="color: red;">转换失败:${data.message}</span>`;
}
} catch (error) {
resultDiv.innerHTML = `<span style="color: red;">请求失败:${error.message}</span>`;
}
});
</script>
</body>
</html>
运行步骤:
- 安装依赖:
npm install express multer - 创建
public目录,放入上述index.html - 运行:
node server.js - 访问:
http://localhost:3000
总结
- 核心功能:Mammoth.js 专注于 .docx 转 HTML/纯文本,支持浏览器和 Node.js 双端,核心方法是
convertToHtml和extractRawText。 - 关键配置:通过
styleMap自定义样式映射,includeEmbeddedImages控制图片处理,可满足大部分格式定制需求。 - 注意事项:仅支持 .docx 格式,复杂样式需自定义映射,大文件建议服务端处理,图片默认转为 Base64 格式。
通过以上教程,你可以掌握 Mammoth.js 的全部核心用法,无论是简单的文档转换,还是带自定义样式、图片的复杂转换场景,都能轻松应对。