• 欢迎访问新概念博客,研究javascript,css3,html5,nodejs,Ext js等技术研究,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入新概念博客

Mammoth.js浏览器js读取Word文档转换成 HTML 文档,页面展示

代码碎片 新概念 2年前 (2022-03-20) 10585次浏览 0个评论 扫描二维码

在应用场景中,有时候我们希望在富文本编辑器中导入已有的 Word 文档进行二次加工,要满足这个需求,我们就需要先把 Word 文档转换成 HTML 文档。要实现这个功能,有 「服务端转换和前端转换」 两种方案:

服务端转换:对于 Java 开发者来说,可以直接基于 POI 项目,POI 是 Apache 的一个开源项目,它的初衷是处理基于 Office Open XML 标准(OOXML)和 Microsoft OLE 2 复合文档格式(OLE2)的各种文件格式的文档,而且支持读写操作。
前端转换:对于前端开发者来说,要想在前端解析 Word 文档,我们首先需要对 Word 文档进行解压,然后再进一步解析解压后的 XML 文档。看起来整个功能实现起来比较繁琐,但值得庆幸的是 Mammoth.js 这个库已经为我们实现上述功能。
在介绍如何利用 Mammoth.js 把之前创建的 Word 文档转换成 HTML 文档前,我们来提前体验一下最终的转换效果。

Mammoth.js 简介

Mammoth.js 旨在转换 .docx 文档(例如由 Microsoft Word 创建的文档),并将其转换为 HTML。 「Mammoth 的目标是通过使用文档中的语义信息并忽略其他细节来生成简单干净的 HTML。」 比如,Mammoth 会将应用标题 1 样式的任何段落转换为 h1 元素,而不是尝试完全复制标题的样式(字体,文本大小,颜色等)。

由于 .docx 使用的结构与 HTML 的结构之间存在很大的不匹配,这意味着对于较复杂的文档而言,这种转换不太可能是完美的。但如果你仅使用样式在语义上标记文档,则 Mammoth 能实现较好的转换效果

当前 Mammoth 支持以下主要特性:

  • Headings
  • Lists,Table
  • Images
  • Bold, italics, underlines, strikethrough, superscript and subscript
  • Links,Line breaks
  • Footnotes and endnotes

它还支持自定义映射规则。例如,你可以通过提供适当的样式映射将 WarningHeading 转换为 h1.warning。另外文本框的内容被视为单独的段落,出现在包含文本框的段落之后。

Mammoth.js 这个库为我们提供了很多方法,这里我们来介绍三个比较常用的 API:

  • mammoth.convertToHtml(input, options):把源文档转换为 HTML 文档
  • mammoth.convertToMarkdown(input, options):把源文档转换为 Markdown 文档。这个方法与 convertToHtml 方法类似,区别就是返回的 result 对象的 value 属性是 Markdown 而不是 HTML。
  • mammoth.extractRawText(input):提取文档的原始文本。这将忽略文档中的所有格式。每个段落后跟两个换行符。

介绍完 Mammoth.js 相关的特性和 API,接下来我们开始进入实战环节。

Mammoth.js 实战

Mammoth.js 这个库同时支持 Node.js 和浏览器两个平台,在浏览器端 mammoth.convertToHtml 方法的 input 参数的格式是 {arrayBuffer: arrayBuffer},其中 arrayBuffer 就是 .docx 文件的内容。在前端我们可以通过 FileReader API 来读取文件的内容,此外该接口也提供了 readAsArrayBuffer 方法,用于读取指定的 Blob 中的内容,一旦读取完成,result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象。下面我们定义一个 readFileInputEventAsArrayBuffer 方法:

export function readFileInputEventAsArrayBuffer(event, callback) {
  const file = event.target.files[0];

  const reader = new FileReader();

  reader.onload = function(loadEvent: Event) {
    const arrayBuffer = loadEvent.target["result"];
    callback(arrayBuffer);
  };

  reader.readAsArrayBuffer(file);
}

该方法用于实现把输入的 File 对象转换为 ArrayBuffer 对象。在获取 Word 文档对应的 ArrayBuffer 对象之后,就可以调用 convertToHtml 方法,把 Word 文档内容转换为 HTML 文档。

mammoth.convertToHtml({ arrayBuffer })

此时如果你的文档中不包括特殊的图片类型,比如 wmf 或 emf 类型,而是常见的 jpg 或 png 等类型的话,那么你可以看到 Word 文档中的图片。难道这样就搞定了,那是不是太简单了,其实这只是个开始。当你通过浏览器的开发者工具审查 Word 解析后的 HTML 文档后,会发现图片都以 Base64 的格式进行嵌入。如果图片不多且单张图片也不会太大的话,那这种方案是可以考虑的。

针对多图或大图的情况,一种比较好的方案是把图片提交到文件资源服务器上。在 Mammoth.js 中要实现上述的功能,可以使用 「convertImage」 配置选项来自定义图片处理器。具体的使用示例如下:

let options = {
    convertImage: mammoth.images.imgElement(function(image) {
      return image.read("base64").then(function(imageBuffer) {
        return {
          src: "data:" + image.contentType + ";base64," + imageBuffer
        };
      });
    })
};

 

以上示例实现的功能就是把 Word 中的图片进行 Base64 编码,然后转成 Data URL 的形式,以实现图片的显示。很明显这不符合我们的要求,所以我们需要做以下调整:

const mammothOptions = {
  convertImage: mammoth.images.imgElement(function(image) {
    return image.read("base64").then(async (imageBuffer) => {
      const result = await uploadBase64Image(imageBuffer, image.contentType);
      return {
        src: result.data.path // 获取图片线上的 URL 地址
      };
    });
  })
};

顾名思义 uploadBase64Image 方法的作用就是上传 Base64 编码后的图片:

async function uploadBase64Image(base64Image, mime) {
  const formData = new FormData();
  formData.append("file", base64ToBlob(base64Image, mime));
  
  return await axios({
    method: "post",
    url: "http://localhost:3000/uploadfile", // 本地图片上传的 API 地址
    data: formData,
    config: { headers: { "Content-Type": "multipart/form-data" } }
  });
}

 

为了减少图片文件的大小,我们需要把 Base64 格式的图片先转成 Blob 对象,然后在通过创建 FormData 对象进行提交。base64ToBlob 方法的定义如下:

function base64ToBlob(base64, mimeType) {
  let bytes = window.atob(base64);
  let ab = new ArrayBuffer(bytes.length);
  let ia = new Uint8Array(ab);
  for (let i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i);
  }
  return new Blob([ia], { type: mimeType });
}

这时把 Word 文档转换为 HTML 并自动把 Word 文档中的图片上传至文件资源服务器的基本功能已经实现了。对于 Mammoth.js 内部是如何解析 Word 中的 XML 文件,我们就不做介绍了,反之我们来简单介绍一下 Mammoth.js 内部依赖的 JSZip 这个库。

 


新概念博客 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Mammoth.js浏览器js读取Word文档转换成 HTML 文档,页面展示
喜欢 (3)
[新概念]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址