前端使用Docx导出Word文档支持Vue3和Angular,React

1,399 阅读3分钟

DOCX介绍

使用JS/TS和一个漂亮的声明式API轻松生成.docx文件。适用于节点和浏览器。.

需求

前端导出word的方法,之前也有尝试不少如 html2canvas 还有使用过jquery.wordexport这两个方法,目前都是不太方便满足我们的项目需求,html2canvas导出太慢,jq的wordexport导出的整体还行,但是是doc的体积较大,同时图片扩展性不太友好,最后我们尝试了docx,基本上实现出了我们需要的效果,在这里记录一下踩坑过程

docx使用

文档地址
npm install docx@6.0.3
先npm安装,推荐6.0.3版本,因为版本7导出速度好像还比版本6慢,后续可能会修复。node环境也可以安装使用,使用方法大家可以去看看我的代码实现,也可以去看官方的案例,基本上搞明白了一个案例就知道怎么去使用docx文档元素的方法了

code-snapshot.png

注意事项(踩坑)

  • 前端使用图片需转换成base64,服务端可以使用fs去读取
  • 必须使用docx包提供的方法去上成文档元素
  • 导出报错xxxxPrimose...这种问题,很有可能是没加await
  • 前端导出需要使用到file-saver 这个包 如果是TS的还需要安装@types/file-saver
  • 返回的是一个doc,我们写的内容主要就在children这个数组里面,new Paragaraph 是docx'元素添加一个新段落,还这次添加表格,段落里面可以插入段落,相当于俄罗斯套娃,段落里面也可以插入图片,表格同理。 new TextRun和其他元素,小伙伴们去文档查看会比我解释的更仔细

抛砖引玉

如果看完文档,还有点迷糊的小伙伴们可以去看看我的code案例,希望能对你有所帮助。同样我写了一个最基本简单的包,easy-word,可以安装,然后就可以直接导出基础图文和基础表格了。在下方可以点击查看,我这是前端使用的方法,服务端导出使用就只有导出导入和图片设置不太一样,整体思路是差不多的

案例代码展示

import { outGraphic } from 'easy-word' 
import { saveAs } from 'file-saver'

const exportWord = async () => {
  // state.downloadflag = !state.downloadflag  弹窗

  // 图片转base64   -- urlToBase64这个是图片转base64的方法
  let num = 0, word: any[] = []
  for (let i = 0, len = state.word.length; i < len; i++) {
    console.log('开始了图片循环', i)
    // state.percentage = ((100 / state.word.length ) * i)<<0 进度条
    let { picture, content, name, time, title } = state.word[i] || {}
    let imgList:any = []
    if (picture.length) {
      for (let img of picture) {
        imgList.push(await urlToBase64(img.url))
      }
    }

    // 必须安装这样的格式去封装数组,才可以正确导出图文,0 第一个元素 最多支持9个元素,图片数组默认是imgList,需要保持参数名一样
    word.push({
      0: title,
      1: `${time}  ${name}`,
      2: content,
      imgList
    })

  }
  // state.ok = true
  console.log(word)
  //   let data:any = []

   /*
    * outGraphic 方法
    * 生成基础 的word文档图文样式
    * @param* `row` — 几行文字 max 10
    * @param* `data` — 数字数组 [{ 0 : val }]
    * @returns* — docx 渲染文档
    */
  const doc:any = await outGraphic(3, word)
  console.warn('获取的', doc)
  Packer.toBlob(doc).then(blob => {
    saveAs(blob, `${自定义文档名称}.docx`)
    console.log('开始保存')
  }).finally(() => {
    console.log('导出成功')
  })
  // 更仔细的查看下方
}

Code展示地址
基础图文样式
基础表格样式

总结

总体来说docx扩展还不错,如果熟悉了文档和写入方法基本上满足大部分导出word文档的需求,文档地址在上方,感兴趣的小伙伴们可以去看看,可以参考我踩坑的一些问题,去自行写出更优雅的word文档导出。我写了两个方法用于一般的文档表格和图文的文档导出感兴趣的小伙伴们可以去看看,如果有更好方法的小伙伴们,欢迎评论交流!