vue导出组件--docxtemplater应用,支持导出office文件----摘抄

1,200 阅读1分钟

(www.cnblogs.com/shenyunjie/…)

1.安装依赖

  npm i docxtemplater -S
npm i docxtemplater-image-module -S
npm i pizzip -S
npm i jszip-utils -S
npm i file-saver -S

2.vue文件引入依赖

import PizZip from "pizzip"
import { saveAs } from "file-saver"
import JSZipUtils from "jszip-utils"
import JSZip from 'jszip'
import ImageModule from "docxtemplater-image-module"
import Docxtemplater from "docxtemplater" 

3 导出文件格式

image.png

注: 字段要对应 文件格式应为.docx 其他格式未尝试

4.vue需要实现的方法

     //   obj{data:[],img:[]}:导出数据  model:导出模板 (存放在public中) title: 导出的文件zip名称与文件夹名称
getExcelWord(obj, model, title) {
  const img = require('../../assets/logo.png')
  if (obj.data.length > 0) {
      // 对需要导出的数据做处理,所要导出的值不能为undefined和null 可以为空字符串
    obj.data.map(item => {
      for (const i in item) {
        if (!item[i]) {
          item[i] = ""
        } else {
          if (Array.isArray(item[i])) {
            item[i].map(item1 => {
              for (const j in item1) {
                if (!item1[j] || item1[j] === null) {
                  item1[j] = ""
                }
              }
            })
          }
        }
      }
    })
    if (obj.img.length > 0) {
      obj.img.map((item, index) => {
        for (const i in item) {
        // 对需要导出的数据图片做处理,所要导出的图片需要转成base64格式的
          if (item[i]) {
            const image = new Image();
            const imageUrl = item[i];
            image.src = imageUrl
            image.onload = () => {
              var canvas = document.createElement('canvas');
              canvas.width = image.width;
              canvas.height = image.height;
              var context = canvas.getContext('2d');
              context.drawImage(image, 0, 0, image.width, image.height);
              var quality = 0.8;
              obj.img[index][`${i}`] = canvas.toDataURL('image/jpeg', quality);
            }
          } else {
            // item[i] = ""
            const image = new Image();
            const imageUrl = img;
            console.log(img, 'img+')
            image.src = imageUrl
            image.onload = () => {
              var canvas = document.createElement('canvas');
              canvas.width = image.width;
              canvas.height = image.height;
              var context = canvas.getContext('2d');
              context.drawImage(image, 0, 0, image.width, image.height);
              var quality = 0.8;
              obj.img[index][`${i}`] = canvas.toDataURL('image/jpeg', quality);
            }
          }
        }
      })
    }
    setTimeout(() => {
      obj.data = obj.data.map((item, index) => {
        const temp = Object.assign({}, obj.data[index], obj.img[index])
        return temp
      })
      const Zip = new JSZip()
      if (obj.data.length > 1) {
      // 批量导出
        obj.data.map(item => {
          JSZipUtils.getBinaryContent(`/${model}`, (error, content) => {
            // model是模板文件的名称。我们在导出的时候,会根据此模板来导出对应的数据
            var opts = {}
            opts.centered = true;
            opts.getImage = function (tagValue, tagName) {
              return new Promise(function (resolve, reject) {
                JSZipUtils.getBinaryContent(tagValue, function (error, content) {
                  if (error) {
                    return reject(error);
                  }
                  return resolve(content);
                });
              });
            }
            // 图片有关代码,没有图片的可以删除
            opts.getSize = function (img, tagValue, tagName) {
              // FOR FIXED SIZE IMAGE :
              return [100, 100];// 图片大小 (这个可以写成动态的,开发文档上有)
            }
            if (error) {
              throw error
            }
            const imageModule = new ImageModule(opts);
            const zip = new PizZip(content);
            // 创建并加载docxtemplater实例对象
            const doc = new Docxtemplater()
              .loadZip(zip).attachModule(imageModule).compile()
            // 设置模板变量的值
            const word = Zip.folder("qrCode")
            doc.resolveData(item).then(function () {
              doc.render();
              const out = doc.getZip().generate({
                type: "blob",
                mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
              });
              word.file(item.name + '.docx', out)
              // 输出文档
              // saveAs(out, "老人.docx");
            })
          })
        })
        setTimeout(() => {
          Zip.generateAsync({ type: "blob" })// zip下载
            .then(function (content) {
              console.log(content, 'content++++++')
              // see FileSaver.js
              saveAs(content, `${title}.zip`);// zip下载后的名字
            })
        }, 2000)
      } else {
        // 单个导出
        JSZipUtils.getBinaryContent(`${model}`, (error, content) => {
          // model是模板文件的名称。我们在导出的时候,会根据此模板来导出对应的数据
          // var ImageModule = require('docxtemplater-image-module-free');
          var opts = {}
          opts.centered = true;
          opts.getImage = function (tagValue, tagName) {
            return new Promise(function (resolve, reject) {
              JSZipUtils.getBinaryContent(tagValue, function (error, content) {
                if (error) {
                  return reject(error);
                }
                return resolve(content);
              });
            });
          }
          // 图片有关代码,没有图片的可以删除
          opts.getSize = function (img, tagValue, tagName) {
            // FOR FIXED SIZE IMAGE :
            return [100, 100];// 图片大小 (这个可以写成动态的,开发文档上有)
          }
          if (error) {
            throw error
          }
          const imageModule = new ImageModule(opts);
          const zip = new PizZip(content);
          // 创建并加载docxtemplater实例对象
          const doc = new Docxtemplater()
            .loadZip(zip).attachModule(imageModule).compile()
          // 设置模板变量的值
          doc.resolveData(obj.data[0]).then(function () {
            doc.render();
            const out = doc.getZip().generate({
              type: "blob",
              mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
            });
            // 输出文档
            saveAs(out, `${title}.docx`);
          })
        })
      }
    }, 1000);
  } else {
    this.$message.error('请先选择导出内容')
  }
}

5 导出之后

image.png

------ 完结 -------

6.导出文件 -- 可看可不看

 

7.模板说明 -- 可看可不看

  {%img} 图片

  {#list}{/list} 循环、if判断

  {#list}{/list}{^list}{/list} if else 

  {str} 文字

  详见:docxtemplater.readthedocs.io/en/latest/t…

8.注 -- 可看可不看

  引入依赖时,使用 npm i,不要使用 cnpm i