学习笔记--Mammoth.js库的使用

0 阅读5分钟

一、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>

运行步骤:

  1. 安装依赖:npm install express multer
  2. 创建 public 目录,放入上述 index.html
  3. 运行:node server.js
  4. 访问:http://localhost:3000

总结

  1. 核心功能:Mammoth.js 专注于 .docx 转 HTML/纯文本,支持浏览器和 Node.js 双端,核心方法是 convertToHtmlextractRawText
  2. 关键配置:通过 styleMap 自定义样式映射,includeEmbeddedImages 控制图片处理,可满足大部分格式定制需求。
  3. 注意事项:仅支持 .docx 格式,复杂样式需自定义映射,大文件建议服务端处理,图片默认转为 Base64 格式。

通过以上教程,你可以掌握 Mammoth.js 的全部核心用法,无论是简单的文档转换,还是带自定义样式、图片的复杂转换场景,都能轻松应对。