一键将Word文档转成Vue组件mammoth的应用详解

 更新时间:2023年02月01日 11:30:07   作者:货拉拉技术  
这篇文章主要为大家介绍了一键将Word文档转成Vue组件mammoth的应用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

在开发后台管理系统的过程中,经常有这样的需求:将 Word 文档(比如用户协议文档)转换为 HTML 页面(Vue 组件)。转换 Word 文档过程通常是枯燥的。开源社区的 mammoth.js 正好可以解压 .docx,并解析 XML 结构,最终将 Word 转成 HTML 文件。因此可以基于该开源库开发「Word 文档转 Vue 组件」工具,让转换流程自动化,从而有效提升了工作效率。本文介绍该工具的实现原理。

mammoth.js 的不足

mammoth.js 虽然可以直接生成 HTML 文件,但是使用过程还是遇到不少问题。比如下图所示的 Word 文档:

经过 mammoth.js 转换后的页面却是这个样子:

从上图我们可以发现以下几个问题:

  • 标题栏不居中
  • 本来是 Word 中的排序,却只是<li></li>默认样式 1 2 3
  • 跟现有的协议规范样式不匹配
  • 超链接没有交互
  • Table 表单不符合预期

改造

因此有必要通过对 mammoth 进行定制来满足当前项目的需求。mammoth 提供了方法可以获取转换后的 AST 节点,那我们就利用这个方法,对 AST 进行转换,最后生成一份可用的 Vue 文件。整个流程如下图所示:

解析 AST

首先先获取 AST。

var options = {
  transformDocument: transformElement,
};
mammoth.convertToHtml({ path }, options).done(async () => {
  // Word处理完毕
});

AST 节点

每个节点都会标明 type 类型、是否居中、字号大小、是否粗体、是否斜体、是否有下划线等。

type 类型如下所示:

Document 根节点

Paragraph 段落

  • Text
  • Run (这种情况,表示 mammoth 把一段话分成几小部分,所以需要拼接 children 内的 text 节点。)
  • hyperlink

Table 表单

  • tableRow
  • tableCell

处理 AST 节点

在处理节点的过程中,有以下几个注意事项:

  • Q: 何时换行?

A: 经观察,type: 'paragraph', children: [] 的时候表示需要换行。

  • Q: 哪些是正标题、副标题

A: 在我们项目中,把居中且字号 16 的文本定义为正标题,居中且字号 14 的文本定义为副标题。

  • Q: 段落首行缩进

A: 这点需要手动处理,默认增加 4 个缩进&nbsp;&nbsp;&nbsp;&nbsp;

  • Q: 如何处理粗体、字号、空格、超链接?

A: 粗体、字号生成公共的 class,比如'bold' 'font-size-14' 'font-size-16';空格需要将\s替换为 &nbsp;;对于 type === 'hyperlink'的超链接,转成<a target="_blank" class="blue" href="${txt.href}">${txt.children[0].value}</a>

  • Q: Word 文档中排序是如何转换的?

A: 用 node 节点中的numbering字段来判断,需要排序则numbering有值;不需要排序则numbering: null; 维护一个公共变量保存排序数值,再将英文数字 1 2 3 等 转换为中文一、二、三等。

  • Q: Table 样式如何处理?

A: 在该节点中,第一个元素为thead标签,后续元素为tbody标签;tbody 中的children节点是由type: paragraph节点构成,可以handleParagraph递归处理。

下面的代码展示了处理段落、表单的逻辑。

function transformElement(element) {
  // 根节点
  const document = element.children;
  if (Array.isArray(document)) {
    document.forEach((ele) => {
      switch (ele.type) {
        case 'paragraph':
          str += handleParagraph(ele);
          break;
        case 'table':
          handleTable(ele);
          break;
        default:
          break;
      }
    });
  }
  return element;
}

代码格式化与生成

首先将字符串拼接成为 Vue 组件源码。

const originalStr = `<template>
  ...
</template>
<script>
 // ...
</script>
<style lang="less" scoped>
  // ...
</style>\n`;

每次给组件起名字也挺烦的,所以可以使用 translate-shell 就根据协议文档的中文名称,进行翻译得出。

// 读取word路径名,并进行翻译,自动生成template name和文件名
function getTranslatedNames(path) {
  return new Promise((resolve) => {
    const chArr = path.replace('.docx', '').split('/');
    exec(
      `trans -t english '${chArr[chArr.length - 1]}'`,
      (error, stdout, stderr) => {
        const arr = stdout.split('\n');
        // ...
        resolve(target.replace(/[^a-zA-Z-]/gi, ''));
      },
    );
  });
}

至此我们已经得到符合项目需求的代码,文件名称也有了,现在只需要将代码内容格式化写入文件就完成了。

// 格式化
const finalStr = prettier.format(originalStr, config);
fs.writeFileSync(`${templateName}.vue`, finalStr, 'utf-8');

最终的效果如下图所示:

总结

简而言之,这个工具站在了 mammoth 的肩膀上,利用 AST 节点,再根据 UI 稿相应地做不同转换。生成符合规范的代码后,再拼接成 vue 组件,写入项目中。mammoth 处理 Word 文档还是非常方便的,推荐使用。

以上就是一键将Word文档转成Vue组件mammoth的应用详解的详细内容,更多关于Word转成Vue组件mammoth的资料请关注脚本之家其它相关文章!

相关文章

  • vue实现无限消息无缝滚动

    vue实现无限消息无缝滚动

    这篇文章主要为大家详细介绍了vue实现无限消息无缝滚动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • vue-cli3全面配置详解

    vue-cli3全面配置详解

    这篇文章主要介绍了vue-cli3全面配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • Vue 自定义组件 v-model 使用详解

    Vue 自定义组件 v-model 使用详解

    这篇文章主要介绍了Vue 自定义组件 v-model 使用介绍,包括vue2中使用和vue3中使用,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • Vue如何解决兄弟组件之间传值问题

    Vue如何解决兄弟组件之间传值问题

    这篇文章主要介绍了Vue如何解决兄弟组件之间传值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • vue+elementUI实现右击指定表格列的单元格显示选择框功能

    vue+elementUI实现右击指定表格列的单元格显示选择框功能

    这篇文章主要介绍了vue+elementUI实现右击指定表格列的单元格显示选择框功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-03-03
  • Vue和SpringBoot之间传递时间的方法实现

    Vue和SpringBoot之间传递时间的方法实现

    本文主要介绍了Vue和SpringBoot之间传递时间的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • vue前端获取/切换麦克风、播放采集音频和采集音量大小完整代码

    vue前端获取/切换麦克风、播放采集音频和采集音量大小完整代码

    这篇文章主要给大家介绍了关于vue前端获取/切换麦克风、播放采集音频和采集音量大小的相关资料,文中通过图文以及代码介绍的非常详细,对大家学习或者使用vue具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-12-12
  • element-ui 中的table的列隐藏问题解决

    element-ui 中的table的列隐藏问题解决

    这篇文章主要介绍了element-ui 中的table的列隐藏问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • vue默认插槽的理解与实例代码

    vue默认插槽的理解与实例代码

    对于插槽的概念和使用,这是vue的一个难点,这需要我们静下心来,慢慢研究,下面这篇文章主要给大家介绍了关于vue默认插槽的相关资料,需要的朋友可以参考下
    2021-11-11
  • Vue3 构建 Web Components使用详解

    Vue3 构建 Web Components使用详解

    这篇文章主要为大家介绍了Vue3 构建 Web Components使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09

最新评论