Vue3 导出word代码,可导出数据+图片

网上搜到的代码都没办法直接使用,需要修改后才能用,我在这里发一版修改后的完美可用的代码,可以直接拿去用,也给自己留个备份。

我在使用网上搜到的代码的时候遇到一些问题,如果你也遇到了这些问题,那么表示这篇文章可以帮助你。

 

问题:

1、JSZIP版本太高(V3.x),导致docxtemplater无法使用,以及一些函数大改动。

2、Vue3使用的Vite而不是Webpack,因此 require,Buffer等功能不能使用。

 

解决方法:

1、手动将JSZIP由3.x改为2.3.0版本,重新npm i,即可解决。

2、Buffer要安装buffer依赖,使用

npm i buffer --save

进行安装,然后直接按如下引用:

import {Buffer} from "buffer";

另外,网络上的代码在加载图片处理依赖时使用的是

var ImageModule = require('docxtemplater-image-module-free');

需要改为

import ImageModule from "docxtemplater-image-module-free";

 

以上就是主要的问题所在,下面贴上完整代码和一些需要注意的东西。

完整代码

1、开始之前,你需要先安装如下依赖

-- 安装 docxtemplater
npm install docxtemplater pizzip  --save

-- 安装 jszip-utils
npm install jszip-utils --save

-- 安装 jszip
npm install jszip --save

-- 安装 FileSaver
npm install file-saver --save

-- 安装 buffer 用作b64转buffer
npm install buffer --save

-- 安装 docxtemplater-image-module-free 用作图片处理
npm install docxtemplater-image-module-free --save

 

2、新建一个js文件,我是在/src/utils/下新建的fileExport.js,并粘贴如下内容。

import PizZip from 'jszip';
import docxtemplater from 'docxtemplater';
import JSZipUtils from 'jszip-utils';
import {saveAs} from 'file-saver';
import {Buffer} from "buffer";
import ImageModule from "docxtemplater-image-module-free";


const 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;
}

/**
 * 导出word,支持图片
 * @param {Object} tempDocxPath 模板文件路径
 * @param {Object} wordData 导出数据
 * @param {Object} fileName 导出文件名
 */
export const exportWord = (tempDocxPath, wordData, fileName, imageSize = {}) => {
    // 读取并获得模板文件的二进制内容
    JSZipUtils.getBinaryContent(tempDocxPath, function (error, content) {
            if (error) {
                throw error;
            }
            let opts = {};
            opts.centered = true; // 图片居中,在word模板中定义方式为{%%image}
            opts.fileType = "docx";
            opts.getImage = function (chartId) {
                return base64DataURLToArrayBuffer(chartId);
            };
            opts.getSize = function (img, tagValue, tagName) {
                // console.log(img);//ArrayBuffer数据
                // console.log(tagValue);//base64数据
                // console.log(tagName);//wordData对象的图像属性名
                // 自定义指定图像大小
                // eslint-disable-next-line no-prototype-builtins
                if (imageSize.hasOwnProperty(tagName)) {
                    return imageSize[tagName];
                } else {
                    return [660, 440];
                }
            }
            let imageModule = new ImageModule(opts);
            // 创建一个PizZip实例,内容为模板的内容
            const zip = new PizZip(content);
            // 创建并加载docxtemplater实例对象
            const doc = new docxtemplater();
            doc.attachModule(imageModule);
            doc.loadZip(zip);

            doc.setData(wordData);

            try {
                // 用模板变量的值替换所有模板变量
                doc.render();
            } catch (error) {
                // 抛出异常
                const e = {
                    message: error.message,
                    name: error.name,
                    stack: error.stack,
                    properties: error.properties
                };
                console.log(
                    JSON.stringify({
                        error: e
                    })
                );
                throw error;
            }
            console.log('11');
            // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
            const out = doc.getZip().generate({
                type: 'blob',
                mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
            });
            // 将目标文件对象保存为目标类型的文件,并命名
            saveAs(out, fileName);
        }
    );
};

 

3、参数说明

  • tempDocxPath 是模板文件绝对路径
  • wordData 模板数据
  • fileName 要保存的文件名
  • imageSize 图片大小,接受一个int对象,格式是{ width, height },单位是px,例如{ 400, 300 }

如需导出图片,则需要将图片转为base64后写入wordData对象内。

echarts转base64的方法是

echarts.getInstanceByDom(document.getElementById('echarts')).getDataURL({
    type: 'png',
    backgroundColor: '#fff',
    pixelRatio: 1,
})

 

4、模板变量

模板内变量要和wordData里的变量名一致。普通字段:{字段名},图片字段:{%字段名}

 

以上

版权声明:
作者:zjh4473
链接:https://blog.zixutech.cn/?p=760
来源:紫旭Blog
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>