前端生成word导出

1.安装插件

npm install docxtemplater pizzip jszip-utils file-saver docxtemplater-image-module-free

2.util文件夹下创建doc.js文件

import docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
import ImageModule from "docxtemplater-image-module-free";
/**
   导出docx
   @param { String } tempDocxPath 模板文件路径
    @param { Object } data 文件中传入的数据
   @param { String } fileName 导出文件名称
*/
export const exportDocx = (tempDocxPath, data, fileName) => {
    // 读取并获得模板文件的二进制内容
    JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => {
        // input.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
        // 抛出异常
        if (error) {
            throw error
        }
        let opts = {};
        opts.centered = false;
        opts.getImage = function (tagValue) {
            return new Promise(function (resolve, reject) {
                JSZipUtils.getBinaryContent(tagValue, function (error, content) {
                    if (error) {
                        return reject(error);
                    }
                    return resolve(content);
                });
            });
        };
        //图片有关代码,没有图片的可以删除
        opts.getSize = (img, tagValue, tagName) => {
            return [200, 105]; //图片大小 (固定的)
            // 非固定(这里是设置宽度最大为300px的图片)
            // return new Promise(function (resolve, reject) {
            //     let image = new Image();
            //     image.src = tagValue;
            //     let imgWidth, imgHeight, scale;
            //     image.onload = function () {
            //         imgWidth = image.width;
            //         imgHeight = image.height;
            //         scale = 0;
            //         if (imgWidth > 300) {
            //             scale = 300 / imgWidth;
            //             imgWidth = 300;
            //             imgHeight = imgHeight * scale;
            //         }
            //         resolve([imgWidth, imgHeight]);
            //     };
            //     image.onerror = function (e) {
            //         console.log("img, tagValue, tagName : ", img, tagValue, tagName);
            //         reject(e);
            //     };
            // });
        };

        let imageModule = new ImageModule(opts);
        // 创建一个JSZip实例,内容为模板的内容
        const zip = new PizZip(content)
        // 创建并加载docxtemplater实例对象
        const doc = new docxtemplater().loadZip(zip).attachModule(imageModule).compile();
        doc.resolveData({ ...data.form }).then(() => {
            doc.render()
            const out = doc.getZip().generate({
                type: 'blob',
                mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
            }) // Output the document using Data-URI
            saveAs(out, fileName)
        }).catch(err => console.log('errorsss', err))
    })
}

3.在public文件夹里创建.docx文档,示例:

word表格里面写的编码的含义:

  • {xxx} 直接渲染数据的xxx字段
  • {#xxx}{/xxx} 循环数组数据
  • {%xxx} 渲染图片

 

4.页面使用

import { exportDocx } from '@/util/doc.js' 
exportWord(){
    const data = {
       form: {
        title: "工作日报",
        officeName: '集团',
        options: [
          {index:1, name:'测试数据1', number: 1, remark:'这是一条备注信息'},
          {index:2, name:'测试数据2', number: 10, remark:'这是一条备注信息'},
        ], //存放表格数据
        filler: '阿强',
        filledTime: '2024-04-24',
        imgList: [{
          img: 'https://images.pexels.com/photos/3291250/pexels-photo-3291250.jpeg?auto=compress&cs=tinysrgb&w=1600&lazy=load'
        },{
        img: 'https://images.pexels.com/photos/3291250/pexels-photo-3291250.jpeg?auto=compress&cs=tinysrgb&w=1600&lazy=load'
        }] //图片数据
      }
    }
    exportDocx('/template.docx', data, `${data.form.title}.docx`)
  },

成果:

 

 

  1. .docx文件一定要自己创建,不要找其他模板改,会报错
  2. 线上的图片路径不存在时,会无法导出,解决方法如下:
  • public文件夹下static文件夹放入‘图片不存在’的png图片,线上图片不存在就加载‘图片不存在的图片’
  • 判断线上图片是否存在的方法:
  • const checkImgExists = (imgurl) => {
          return new Promise(function (resolve, reject) {
            var ImgObj = new Image();
            ImgObj.src = imgurl;
            ImgObj.onload = function () {
              resolve(imgurl);
            };
            ImgObj.onerror = function (err) {
              reject("/static/img/failImg.png");
            };
          });
        }
        
        //imageList,后端返回的数组图片数据
        imageList.map(async (item) => {
              const res = await this.checkImgExists(item);
                return {
                    img: res,
                };
         });
         Promise.all(newImgList).then((res) => {
              data.imgList = res
         })
    

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值