首页 > 其他分享 >前端实现根据模版导出word【docxtemplater】

前端实现根据模版导出word【docxtemplater】

时间:2024-07-02 22:20:06浏览次数:18  
标签:function word name 模版 image content new docxtemplater const

场景

有的时候我们需要根据后端提供的数据,然后结合word模版来生成word。我们可以使用第三方库docxtemplater

效果

依赖说明

1、docxtemplater:这个插件可以通过预先写好的word,excel等文件模板生成对应带数据的文件
2、pizzip:这个插件用来创建,读取或编辑.zip的文件(同步的,还有一个插件是jszip,异步的)
3、jszip-utils:与jszip/pizzip一起使用,jszip-utils 提供一个getBinaryContent(path, data)接口,path即是文件的路径,支持AJAX get请求,data为读取的文件内容。
4、file-saver:适合在客户端生成文件的工具,它提供的接口saveAs(blob, "1.docx")将会使用到,方便我们保存文件。
5、docxtemplater-image-module-free:需要导出图片的话需要这个插件

代码

App.vue

<template>
  <div class="app">
    <el-divider content-position="center">1.基本使用</el-divider>
    <el-button type="primary" @click="exportWord_1">导出word</el-button>

    <el-divider content-position="center">2.带有表格的导出</el-divider>
    <el-button type="primary" @click="exportWord_2">导出word</el-button>

    <el-divider content-position="center">3.带有图片的导出</el-divider>
    <el-button type="primary" @click="exportWord_3">导出word</el-button>
  </div>
</template>

<script>
import Docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
import PizZipUtils from 'pizzip/utils/index.js'
import { saveAs } from 'file-saver'
// import ImageModule from 'docxtemplater-image-module/build/imagemodule'
import ImageModule from 'docxtemplater-image-module-free'

import logo from '@/assets/1.png'

export default {
  data() {
    return {}
  },
  methods: {
    exportWord_1() {
      PizZipUtils.getBinaryContent('/word/template.docx', (err, content) => {
        if (err) {
          throw err
        }
        const zip = new PizZip(content)
        const doc = new Docxtemplater(zip, {
          paragraphLoop: true,
          linebreaks: true,
        })
        doc.render({
          title: '邮件标题',
          name: 'Coder',
          content: '这是一封测试邮件',
          signer: 'Me',
          sign_time: '2024/07/02',
        })

        const out = doc.getZip().generate({
          type: 'blob',
          mimeType:
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        })
        saveAs(out, 'Test.docx')
      })
    },
    exportWord_2() {
      PizZipUtils.getBinaryContent('/word/template.docx', (err, content) => {
        if (err) {
          throw err
        }
        const zip = new PizZip(content)
        const doc = new Docxtemplater(zip, {
          paragraphLoop: true,
          linebreaks: true,
        })
        doc.render({
          title: '邮件标题',
          name: 'Coder',
          content: '这是一封测试邮件',
          signer: 'Me',
          sign_time: '2024/07/02',
          movie_list: [
            {
              name: '盗梦空间',
              price: 56,
              release_date: '2013-06-03',
            },
            {
              name: '斗破苍穹',
              price: 46,
              release_date: '2024-01-03',
            },
            {
              name: '疯狂的麦克斯*狂暴女神',
              price: 76,
              release_date: '2024-07-02',
            },
          ],
        })

        const out = doc.getZip().generate({
          type: 'blob',
          mimeType:
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        })
        saveAs(out, 'Test.docx')
      })
    },
    exportWord_3() {
      // 官方示例,尝试不成功
      /*
        const imageOptions = {
          getImage(url) {
            return new Promise(function (resolve, reject) {
              PizZipUtils.getBinaryContent(url, function (error, content) {
                if (error) {
                  return reject(error)
                }
                return resolve(content)
              })
            })
          },
          getSize(img, url, tagName) {
            return new Promise(function (resolve, reject) {
              const image = new Image()
              image.src = url
              image.onload = function () {
                resolve([image.width, image.height])
              }
              image.onerror = function (e) {
                console.log('img, url, tagName : ', img, url, tagName)
                alert('An error occured while loading ' + url)
                reject(e)
              }
            })
          },
        }

        PizZipUtils.getBinaryContent('/word/template.docx', (err, content) => {
          if (err) {
            throw err
          }
          const zip = new PizZip(content)
          const doc = new Docxtemplater(zip, {
            paragraphLoop: true,
            linebreaks: true,
            modules: [new ImageModule(imageOptions)],
          })
          doc
            .renderAsync({
              logo: logo,
              title: '邮件标题',
              name: 'Coder',
              content: '这是一封测试邮件',
              signer: 'Me',
              sign_time: '2024/07/02',
              movie_list: [
                {
                  name: '盗梦空间',
                  price: 56,
                  release_date: '2013-06-03',
                },
                {
                  name: '斗破苍穹',
                  price: 46,
                  release_date: '2024-01-03',
                },
                {
                  name: '疯狂的麦克斯*狂暴女神',
                  price: 76,
                  release_date: '2024-07-02',
                },
              ],
            })
            .then(function () {
              const out = doc.getZip().generate({
                type: 'blob',
                mimeType:
                  'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
              })
              saveAs(out, 'Test.docx')
            })
        })
      */

      PizZipUtils.getBinaryContent('/word/template.docx', (err, content) => {
        if (err) {
          throw err
        }

        var opts = {}
        opts.centered = false
        opts.getImage = function (tagValue, tagName) {
          return new Promise(function (resolve, reject) {
            PizZipUtils.getBinaryContent(tagValue, function (error, content) {
              if (error) {
                return reject(error)
              }
              return resolve(content)
            })
          })
        }
        opts.getSize = function (img, tagValue, tagName) {
          // FOR FIXED SIZE IMAGE :
          return [150, 150]

          // FOR IMAGE COMING FROM A URL (IF TAGVALUE IS AN ADRESS) :
          // To use this feature, you have to be using docxtemplater async
          // (if you are calling setData(), you are not using async).
          return new Promise(function (resolve, reject) {
            var image = new Image()
            image.src = url
            image.onload = function () {
              resolve([image.width, image.height])
            }
            image.onerror = function (e) {
              console.log('img, tagValue, tagName : ', img, tagValue, tagName)
              alert('An error occured while loading ' + tagValue)
              reject(e)
            }
          })
        }

        var imageModule = new ImageModule(opts)

        const zip = new PizZip(content)
        const doc = new Docxtemplater()
          .loadZip(zip)
          .attachModule(imageModule)
          .compile()

        doc
          .resolveData({
            logo: logo,
            title: '邮件标题',
            name: 'Coder',
            content: '这是一封测试邮件',
            signer: 'Me',
            sign_time: '2024/07/02',
            movie_list: [
              {
                name: '盗梦空间',
                price: 56,
                release_date: '2013-06-03',
              },
              {
                name: '斗破苍穹',
                price: 46,
                release_date: '2024-01-03',
              },
              {
                name: '疯狂的麦克斯*狂暴女神',
                price: 76,
                release_date: '2024-07-02',
              },
            ],
          })
          .then(function () {
            doc.render()
            var out = doc.getZip().generate({
              type: 'blob',
              mimeType:
                'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            })
            saveAs(out, 'test-image.docx')
          })
      })
    },
  },
}
</script>

<style lang="less" scoped>
.app {
  padding: 40px;
}
</style>

public/word/template.docx

参考文档

标签:function,word,name,模版,image,content,new,docxtemplater,const
From: https://www.cnblogs.com/it774274680/p/18280653

相关文章

  • 如何更改Wordpress语言为中文
    在使用WordPress的时候,一般安装默认语言是英文,可以在后台设置里面直接修改站点语言为简体中文,当后台没有语言选项框的这一栏,如下图所示,该怎么办呢? 这个时候我们可以找到文件wp-config.php文件,添加一行代码  define('WPLANG','zh_CN');  保存后,然后我们回到后台到设置......
  • 学习笔记484—Word加载项是灰色怎么解决 Word加载项是灰色的解决方法【详解】
    Word加载项是灰色怎么解决?在Word2016拥有一个加载项的功能,加载项其实就是Word插件,可以实现很多Word自己无法实现的功能,近期有用户发现自己电脑上的Word加载项是灰色的无法使用,这该怎么解决呢?下面我们来看看吧。具体操作如下:1、首先我们打开Word。具体查看图片哦。我这个......
  • WordPress 5.5+ 如何自定义XML 站点地图功能
    关键要点在WordPress5.5中,WordPress将导出一个站点地图索引文件/wp-sitemap.xml。这是主要的XML文件,其中包含WordPress网站公开的所有站点地图页面的列表。该站点地图索引最多可容纳50000个站点地图,单个站点地图最多可容纳2000个条目(可过滤)。默认情况下,将为所有公开和可公开查......
  • Typora导出为Word
    目录一、场景二、安装1、网址2、解压并验证三、配置四、重启Typora一、场景在使用Typora软件编辑文档时,我们可能需要将其导出为Word格式文件当然我们可以直接在菜单里进行导出操作文件->导出->Word(.docx)如果是第一次导出word文件,那么会提示你要安装Pandoc,才能导出wor......
  • 玄机——第四章 windows实战-wordpress wp
    文章目录一、前言二、概览简介三、参考文章四、步骤(解析)准备阶段1.01.1请提交攻击者攻击成功的第一时间,格式:flag{YY:MM:DDhh:mm:ss}1.2请提交攻击者的浏览器版本flag{Firgfox/2200}1.3请提交攻击者目录扫描所使用的工具名称1.4找到攻击者写入的恶意后门文件,提交文......
  • 【模版】最短路
    原创于2017.04.03:最短路1.多源的Floyd,邻接矩阵实现,复杂度O(n^3),n<400;2.单源Dijkstra,邻接矩阵实现,无负边,复杂度O(n^2),n<10000;3.单源Dijkstra,邻接表实现,堆优化,无负边,复杂度O(ElogE),点多边少;4.单源bellman_ford,边集实现,可验负环,复杂度O(nE),nm<10^8;5.单源SPFA,邻接表+队列实现,可验负环......
  • Java 将Markdown文件转换为Word和PDF文档
    Markdown凭借其简洁易用的特性,成为创建和编辑纯文本文档的常用选择。但某些时候我们需要更加精致的展示效果,例如在专业分享文档或打印成离线使用的纸质版时,就需要将Markdown文件以其他固定的文档格式呈现。通过将Markdown转换为Word和PDF格式,可以得到更多的格式设置,确保跨......
  • 阿里云服务器数据库迁云: 数据从传统到云端的安全之旅(WordPress个人博客实战教学)
    ......
  • 某大型建设集团有限公司信息化技术方案(250页WORD)
    方案介绍:本信息化技术方案旨在构建一个集成度高、功能全面、操作简便的信息化系统,涵盖公司管理、业务运营、项目监控、数据分析等多个方面。通过引入云计算、大数据、物联网、人工智能等先进技术,实现资源的优化配置、流程的高效协同和数据的智能分析,从而提升公司的整体竞争力。......
  • 【漏洞复现】WordPress MasterStudy LMS插件 SQL注入漏洞(CVE-2024-1512)
    0x01产品简介WordPress和WordPressplugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPressplugin是一个应用插件。0x02漏洞概述WordPressPluginMasterStudyLMS3.2.5版本......