zoukankan      html  css  js  c++  java
  • Vue+docxtemplater导出到word(包含批量转出图片)!!!

    首先需要先装依赖:

    //-- 安装 docxtemplater
    npm install docxtemplater pizzip  --save
    npm install docxtemplater@3.5
    //
    docxtemplater@3.5 不然会报错 part..什么的
    //-- 安装 jszip-utils
    npm install jszip-utils --save 
    //-- 安装 jszip
    npm install jszip --save
    //-- 安装 FileSaver
    npm install file-saver --save
    //安装 docxtemplater-image-module-free
    npm install --save docxtemplater-image-module-free 
    
    
    export(){
          var ImageModule = require('open-docxtemplater-image-module');
          let that=this
          JSZipUtils.getBinaryContent("../../../static/template/模板表.docx", function (error, content) {
            // model.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
            // 抛出异常
            if (error) {
              throw error;
            }
            // 创建并加载docxtemplater实例对象
            const doc = new docxtemplater();
            // 创建一个PizZip实例,内容为模板的内容
            const zip = new PizZip(content);
            doc.loadZip(zip)
            // 图片处理
            const opts = {}
            opts.centered = true;  // 图片居中,在word模板中定义方式为{%image}
            opts.fileType = "docx";
            opts.getImage = (chartId) =>{
              return that.base64DataURLToArrayBuffer(chartId);
            }
            opts.getSize = function(){
              return [600,900]
            }
            let imageModule = new ImageModule(opts);
            doc.attachModule(imageModule);
            // 设置模板变量的值,我的是一条数据里有多个图片,因此需要split一下。看个人情况写就行。主要就是把图片地址去转成base64后,在存给src
            if (that.ajmlList.length > 0) {
              for (let i = 0; i < that.ajmlList.length; i++) {
                if(!_.isEmpty(that.ajmlList[i].filePath)){
                  let arr=that.ajmlList[i].filePath.split(',')
                  for (let j = 0; j < arr.length; j++) {
                    that.UrlToBase64(arr[j], (dataURL) => {
                      that.dataUrl.push({
                        src: dataURL
                      })
                    })
                  }
                }
              }
            }
    //因为我转base64的时候是异步的,这只能设置一下等待时间了~ setTimeout(()
    => { that.docxData = { buyUnit:that.obj.passinfo.buyUnit,//类似这样,与模板对应上 普通字段模板里就写{buyUnit} images: that.dataUrl //批量图片 模板里复杂一些 {#images} {%image} {/} }; doc.setData({ ...that.docxData }); try { // 用模板变量的值替换所有模板变量 doc.render(); } catch (error) { // 抛出异常 let e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties }; console.log(JSON.stringify({error: e.message})); throw error; } // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示) let out = doc.getZip().generate({ type: "blob", mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); // 将目标文件对象保存为目标类型的文件,并命名 saveAs(out, "测试.docx"); }, 4000); }); }
    //带回调的办法   
     UrlToBase64(url, callback) {
          let  image= new Image();
          let that=this
          //解决跨域问题
          image.setAttribute('crossOrigin', 'anonymous');
          image.src = url
          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;
            //这里的dataurl就是base64类型
            var dataURL = canvas.toDataURL("image/png", quality);
            callback ? callback(dataURL) : null; //调用回调函数
          }
    
        },
    //官网里的方法,没仔细看
    base64DataURLToArrayBuffer(dataURL) {
    const base64Regex = /^data:image/(png|jpg|svg|svg+xml);base64,/;
    if (!base64Regex.test(dataURL)) {
    return false;
    }
    const stringBase64 = dataURL.replace(base64Regex, "");
    let binaryString;
    if (typeof window !== "undefined") {
    binaryString = window.atob(stringBase64);
    } else {
    binaryString = new Buffer(stringBase64, "base64").toString("binary");
    }
    const len = binaryString.length;
    const bytes = new Uint8Array(len);
    for (let i = 0; i < len; i++) {
    const ascii = binaryString.charCodeAt(i);
    bytes[i] = ascii;
    }
    return bytes.buffer;
    },
     

    官网链接:https://docxtemplater.com/

    本文来自博客园,作者:哈利波特甜,转载请注明原文链接:https://www.cnblogs.com/zmh-980509/p/15480113.html

  • 相关阅读:
    java 事件监听机制组成
    关于父进程和子进程的关系(UAC 绕过思路)
    Fort.js – 时尚、现代的进度提示效果
    Hive学习之函数DDL和Show、Describe语句
    js完美的div拖拽实例代码
    SSH2框架实现注冊发短信验证码实例
    再看C#中的托付和事件
    RGB(FFFFFF)转255:255:255
    单一目的聚集操作
    智慧城市,在中国的北海边再画一个圈——大连“中国首届智慧城市协同创新峰会”请你带好笔
  • 原文地址:https://www.cnblogs.com/zmh-980509/p/15480113.html
Copyright © 2011-2022 走看看