JavaScript实现纯前端提取Word文本的完整教程

 更新时间:2026年08月08日 08:54:01   作者:Eiceblue  
在日常前端开发中,Word 文档的文本提取是一个高频需求,本文将结合 React 技术栈,为大家详细介绍如何使用 Spire.Doc for JavaScript 实现 Word 文档文本的提取与下载,希望对大家有所帮助

在日常前端开发中,Word 文档的文本提取是一个高频需求 —— 在线文档预览、内容检索、格式校验、数据入库等场景都依赖这一能力。传统方案往往需要将文件上传到后端服务器进行处理,不仅增加了带宽消耗和服务器负载,还带来了数据隐私方面的隐患。

Spire.Doc for JavaScript 提供了一种全新的解决思路 — 直接在浏览器端通过 WebAssembly 完成 Word 文档的读取与文本提取,无需任何后端服务支持。

本文将结合 React 技术栈,详细介绍如何使用 Spire.Doc for JavaScript 实现 Word 文档文本的提取与下载。

一、核心技术原理

1.1 WASM 运行机制

Spire.Doc for JavaScript 本质是将高性能原生文档处理内核编译为 WebAssembly,在浏览器沙箱中运行。整个加载流程分为三步:

  • 加载 JS 胶水层:spire.doc.js 负责 WASM 模块的初始化与 API 暴露
  • 编译 WASM 二进制:浏览器下载 .wasm 文件并编译为本地机器码
  • 初始化运行时:构建虚拟文件系统(VFS),准备完整的运行环境

1.2 虚拟文件系统(VFS)

WASM 运行在沙箱中,无法直接访问本地文件系统。Spire.Doc 通过 Emscripten 提供的 FS 接口模拟了一套虚拟文件系统:

  • 调用 FS.writeFile 将用户上传的文件写入 VFS
  • 调用 FS.unlink 清理临时文件
  • 字体文件同样需要预加载到 VFS 中

1.3 文本提取核心 API

Document.GetText() 是提取纯文本的核心方法,它会遍历文档所有章节、段落、文本框,按顺序拼接所有可编辑文本内容,保留换行符以维持段落结构。

二、环境配置与项目初始化

2.1 安装依赖

首先,在 React 项目中安装并整合了多个组件的 Spire.Office:

npm i spire.office

该产品提供免费社区版(使用时注意限制)。

2.2 迁移核心运行时文件

安装完成后,需要将 node_modules 中 Spire.Doc for JavaScript 的运行时文件复制到 React 项目的 public 文件夹中:

  • spire.doc.js
  • spire.doc.wasm
  • spire.common.js
  • spire.common.wasm
  • _framework 文件夹

为什么放在 public 目录?

因为 WASM 的加载需要通过 JavaScript 主线程以异步方式请求 .wasm 文件及相关资源。放在 public 目录下可以确保构建工具(如 Webpack)不会错误地处理或重命名这些文件,且能通过 process.env.PUBLIC_URL 准确访问。

2.3 准备字体资源

浏览器和 WASM 环境默认不包含系统字体。如果待处理的 Word 文档中使用了特殊字体(如 Calibri、Times New Roman 或中文字体),而 VFS 中缺失该字体,提取出的文本可能会出现乱码或文本错位。

建议将项目常用字体文件(如 Arial.ttf、CALIBRI.ttf、MSYH.TTC 等)一并放入 public/font/ 目录。

三、提取 Word 文本 - React 完整实现方案

下面以 React 函数组件为例,完整实现「文件上传 → 解析提取 → 导出下载」的全流程。

3.1 加载 WASM 模块

import React, { useState, useEffect } from 'react';

function App() {
  const [wasmModule, setWasmModule] = useState(null);
  const [selectedFile, setSelectedFile] = useState(null);
  const [isExtracting, setIsExtracting] = useState(false);
  const [error, setError] = useState(null);
  const [fontLoaded, setFontLoaded] = useState(false);

  // 加载 Spire.Doc WASM 模块
  useEffect(() => {
    (async () => {
      try {
        const publicUrl = process.env.PUBLIC_URL || '';
        const spireModule = await import(
          /* webpackIgnore: true */ `${publicUrl}/spire.doc.js`
        );
        const rawModule = spireModule.default || spireModule;
        window.wasmModule = typeof rawModule === 'function'
          ? await rawModule({
              locateFile: (p) =>
                p.endsWith('.wasm') ? `${publicUrl}/${p}` : p,
            })
          : rawModule;
        setWasmModule(window.wasmModule);
      } catch (err) {
        console.error('WASM 加载失败:', err);
        setError('无法加载文档处理引擎,请刷新页面重试。');
      }
    })();
  }, []);

这里的关键点是使用动态 import() 加载 spire.doc.js,并通过 locateFile 回调指定 WASM 文件的路径。/* webpackIgnore: true */ 注释确保 Webpack 不会尝试打包这个动态导入的模块。

3.2 文件选择与状态管理

  const handleFileChange = (event) => {
    const file = event.target.files[0];
    if (file) {
      setSelectedFile(file);
      setError(null);
    }
  };

文件选择逻辑简洁明了,用户选择文件后将其存入状态,同时清除之前的错误信息。

3.3 文本提取核心函数

这是整个组件的核心部分,完整实现了从文件读取到文本提取再到下载的全流程:

  const extractTextFromUploadedFile = async () => {
    if (!selectedFile) {
      setError('请先选择一个 Word 文档。');
      return;
    }

    const wasmDoc = window.wasmModule?.spiredoc;
    if (!wasmDoc) {
      setError('文档引擎尚未加载,请稍候。');
      return;
    }

    setIsExtracting(true);
    setError(null);

    try {
      // 3.3.1 预加载字体(仅加载一次)
      if (!fontLoaded) {
        await window.spire.FetchFileToVFS(
          'Arial.ttf',
          '/Library/Fonts/',
          `${process.env.PUBLIC_URL}/static/font/`
        );
        setFontLoaded(true);
      }

      // 3.3.2 将用户上传的文件读为 Uint8Array
      const arrayBuffer = await selectedFile.arrayBuffer();
      const uint8Array = new Uint8Array(arrayBuffer);
      const fileName = selectedFile.name;

      // 写入 VFS
      window.dotnetRuntime.Module.FS.writeFile(fileName, uint8Array);

      // 3.3.3 创建 Document 实例并加载文件
      const doc = new wasmDoc.Document();
      doc.LoadFromFile(fileName);

      // 3.3.4 提取全部文本
      const documentText = doc.GetText();

      // 3.3.5 释放资源
      doc.Dispose();

      // 3.3.6 下载文本文件
      const blob = new Blob([documentText], { type: 'text/plain;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `extracted_${selectedFile.name.replace(/\.[^.]+$/, '')}.txt`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);

      // 清理 VFS 中的临时文件
      window.dotnetRuntime.Module.FS.unlink(fileName);

      // 重置状态
      setSelectedFile(null);
      document.getElementById('fileInput').value = '';
    } catch (err) {
      console.error('提取失败:', err);
      setError(`提取失败:${err.message || '未知错误'}`);
    } finally {
      setIsExtracting(false);
    }
  };

代码解析:

  • 预加载字体:FetchFileToVFS 方法将 public/static/font/ 目录下的 Arial.ttf 字体文件加载到 WASM 的虚拟文件系统中,映射到 /Library/Fonts/ 路径。
  • 文件写入 VFS:通过 File.arrayBuffer() 获取文件的二进制数据,构造 Uint8Array,然后使用 FS.writeFile 将文件写入 WASM 的虚拟文件系统。
  • 创建 Document 并加载: 实例化 Document 对象,调用 LoadFromFile 方法从 VFS 中加载 Word 文档。
  • 提取文本:调用 Document.GetText() 方法即可获取文档中的所有文本内容。
  • 资源释放: 调用 Dispose() 方法释放 Document 对象占用的 WASM 内存资源,防止内存泄漏。
  • 下载与清理:将提取的文本封装为 Blob 对象,创建下载链接并触发浏览器下载。下载完成后清理临时创建的 URL 对象,并从 VFS 中删除临时文件。

3.4 UI 渲染

  return (
    <div style={{ maxWidth: '600px', margin: '50px auto', textAlign: 'center' }}>
      <h1>📄 从 Word 提取文本</h1>
      <p style={{ color: '#666' }}>选择本地的 .doc 或 .docx 文件,提取全部文本内容</p>
      <div style={{ margin: '30px 0' }}>
        <input
          id="fileInput"
          type="file"
          accept=".doc,.docx"
          onChange={handleFileChange}
          disabled={!wasmModule || isExtracting}
          style={{ display: 'none' }}
        />
        <label
          htmlFor="fileInput"
          style={{
            display: 'inline-block',
            padding: '10px 20px',
            background: '#f0f0f0',
            borderRadius: '4px',
            cursor: 'pointer',
            border: '1px solid #ccc',
          }}
        >
          {selectedFile ? `已选:${selectedFile.name}` : '选择 Word 文档'}
        </label>
      </div>
      {selectedFile && (
        <button
          onClick={extractTextFromUploadedFile}
          disabled={!wasmModule || isExtracting}
          style={{
            padding: '12px 30px',
            fontSize: '16px',
            backgroundColor: '#007bff',
            color: '#fff',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer',
            marginTop: '10px',
          }}
        >
          {isExtracting ? '提取中...' : '提取并下载文本'}
        </button>
      )}
      {error && (
        <div style={{ marginTop: '20px', color: '#d32f2f', background: '#ffebee', padding: '10px', borderRadius: '4px' }}>
          {error}
        </div>
      )}
      {!wasmModule && !error && (
        <div style={{ marginTop: '20px', color: '#888' }}>⏳ 文档引擎加载中,请稍候...</div>
      )}
    </div>
  );
}
export default App;

UI 部分提供了完整的用户交互反馈:文件选择、加载状态、错误提示和引擎加载进度。

3.5 启动开发服务器

将以上完整 App 组件代码复制到 src/App.js 文件中并保存。在项目根目录执行:

npm start

该命令会启动 React 开发服务器,默认在 http://localhost:3000 打开应用。

点击“选择 Word 文档”按钮,上传本地的 .doc 或 .docx 文件。

点击“提取并下载文本”按钮,稍等片刻即可自动下载提取出的 .txt 文件。

四、进阶技巧 - 提取指定段落或节的文本

如果不需要提取整个文档的文本,可以使用更精细的 API:

const doc = new wasmDoc.Document();
doc.LoadFromFile(fileName);

// 获取第一个节(Section)
const section = doc.Sections.get_Item(0);
// 获取该节中的第一个段落
const paragraph = section.Paragraphs.get_Item(0);
// 提取该段落的文本
const text = paragraph.Text;

五、总结

通过以上示例,可以在浏览器端实现 Word 文档处理能力,让前端文本提取不再依赖后端服务。本文完整拆解了 React 环境下的实现方案,从 WASM 初始化、虚拟文件系统操作,到资源释放与异常处理,覆盖了生产环境所需的全部细节。

Spire.Doc for JavaScript 支持的 Word 文档格式涵盖 Word 97-2003 到 Word 2019 的所有版本,并支持将 DOC/DOCX 文件转换为 TXT、HTML、PDF、图片等多种格式。

以上就是JavaScript实现纯前端提取Word文本的完整教程的详细内容,更多关于JavaScript提取Word文本的资料请关注脚本之家其它相关文章!

相关文章

  • JavaScript获取当前日期与时间的方法示例详解

    JavaScript获取当前日期与时间的方法示例详解

    这篇文章主要介绍了JavaScript获取当前日期与时间的方法,以下是一些js中常见的时间操作案例,这些案例涵盖了日期和时间的获取、格式化、计算等操作,帮助你在实际开发中处理时间相关的问题,需要的朋友可以参考下
    2025-07-07
  • JavaScript动态添加style节点的方法

    JavaScript动态添加style节点的方法

    这篇文章主要介绍了JavaScript动态添加style节点的方法,涉及javascript节点操作的相关技巧,需要的朋友可以参考下
    2015-06-06
  • 详述 Sublime Text 打开 GBK 格式中文乱码的解决方法

    详述 Sublime Text 打开 GBK 格式中文乱码的解决方法

    这篇文章主要介绍了详述 Sublime Text 打开 GBK 格式中文乱码的解决方法,非常具有实用价值,需要的朋友可以参考下
    2017-10-10
  • Javascript 获取链接(url)参数的方法

    Javascript 获取链接(url)参数的方法

    Javascript 获取链接(url)参数的实现方法
    2009-02-02
  • javascript中为某个元素指定事件的三种方式

    javascript中为某个元素指定事件的三种方式

    在javascript中,可以为某个元素指定事件,指定的方式有以下三种使用onclick属性,使用addEvenListener()方法
    2014-08-08
  • js 幻灯片的实现

    js 幻灯片的实现

    今天在群里看到有人要幻灯片的代码,于是我自己也想了想,做个总结。常见的幻灯片切换无非就是轮播和渐变,不管哪种都是用定时器来逐步改变图片或者图片组的某种属性来实现的
    2011-12-12
  • countUp.js实现数字滚动效果

    countUp.js实现数字滚动效果

    这篇文章主要为大家详细介绍了countUp.js实现数字滚动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • javascript 主动派发事件总结

    javascript 主动派发事件总结

    有时需要模仿用户的一些动作(鼠标/键盘操作),最常见的莫过于鼠标点击。一一列举
    2011-08-08
  • js实现在同一窗口浏览图片

    js实现在同一窗口浏览图片

    在同一窗口浏览图片的方法有很多,本例要为大家介绍的是使用js获取img的src属性后进行替换
    2014-09-09
  • 微信小程序拖拽排序列表的示例代码

    微信小程序拖拽排序列表的示例代码

    这篇文章主要介绍了微信小程序拖拽排序列表的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论