前端基于word模板导出word文档

news2025/2/24 5:43:44

项目环境

vue2 + js + vue-cli等

依赖包都可以在npm官网找到对应文档 npm官网(英文)

1、依赖

安装依赖

docxtemplater

npm i docxtemplater

file-saver

npm i file-saver

jszip-utils

npm i jszip-utils

jszip

npm i jszip

在对应页面或模块中引入依赖

import Docxtemplater from "docxtemplater";
import { saveAs } from "file-saver";
import JSZipUtils from "jszip-utils";
import JSZip from 'jszip';

2、准备word模板

导出需要依据准备好的word模板导出,word模板放置在vue项目中的public文件夹下;

模板书写依据 docxtemplater ,其是一个用于处理和生成Word文档的模板引擎,使用类似于标签的语法来标记需要被替换或插入的内容;

常见语法:

  1. 替换变量:使用大括号 { } 将要替换的变量包裹起来。例如:{ 变量名称 }。在运行时,你可以通过提供一个数据对象来替换这些变量。

小技巧:如果有很多需要替换的变量,那么可以把这些变量通过编码的方式糅合成一个或几个大变量后再实现替换,降低工作量,同时也可以实现更高的word文档自定义

  1. 循环迭代:使用 {{#each}}{{/each}} 标签来循环迭代一个数组,并在每次迭代中生成相应的内容。
{{#each students}}
Name: {{name}}, Age: {{age}}
{{/each}}

students 为一个包含学生数组的数据对象 ; 每个数组项都包含name和age属性

  1. 条件判断:使用 {{#if}}{{/if}} 标签来进行条件判断,并根据条件的真假来生成相应的内容
{{#if isPassed}}
Congratulations! You have passed the exam.
{{else}}
Sorry, you did not pass the exam.
{{/if}}
  1. 图片

    {%img}

    {%%img} 图片在word中居中

模板里的所定义的变量名称,要和程序中定义的变量名称一样,这样才能成功实现替换

模板案例
在这里插入图片描述

3、编码导出

    // 根据项目需求的不同,需要修改导出函数中的内容
    // 切记,在触发该导出函数前 先把 doc.setData() 中需要的数据先装好 
    handleExport(){
      //这里要引入处理图片的插件,下载docxtemplater后,引入的就在其中了
      var ImageModule = require("docxtemplater-image-module-free");
      // 读取并获得模板文件的二进制内容
      JSZipUtils.getBinaryContent("YangGuangFile.docx", (error, content) => {
      // YangGuangFile.docx 这里是word模板文档的路径,该项目而言在public根目录下,所以,直接写文件名即可
        if (error) {
          throw error;
        }
        // 图片处理
        let opts = {};
        opts = { centered: false };
        opts.getImage = (chartId) => {
          return this.base64DataURLToArrayBuffer(chartId);
        };
        opts.getSize = function (img, tagValue, tagName) {
          //自定义指定图像大小 根据文件名 规定导出的图片大小
          if (tagName === "img1" || tagName === "img2") {
            return [600, 200];
          }
          if (tagName === "img3" || tagName === "img4" || tagName === "img5") {
            return [200, 400];
          }
        };

        // 创建一个PizZip实例,内容为模板的内容
        let zip = new PizZip(content);
        // 创建并加载docxtemplater实例对象
        let doc = new docxtemplater();
        doc.attachModule(new ImageModule(opts));
        doc.loadZip(zip);
        // copyWorldData 是一个对象,包含很多变量,变量名和word模板中定义好的变量名一一对应,其中就有year1,month1等等
        // img1  就是导出图片的名称,也和word模板中定义的图片名一一对应
        // this.$refs.pictureLine1.getChartImg() 在父组件通过ref的方式调用子组件里的getChartImg()方法生成图片
        // 这里的所用的图片子组件是 echarts 二次封装而成的组件
        doc.setData({
          ...copyWorldData,
          img1: this.$refs.pictureLine1.getChartImg(),
          img2: this.$refs.pictureLine2.getChartImg(),
          img3: this.$refs.pictureLine3.getChartImg(),
          img4: this.$refs.pictureLine4.getChartImg(),
          img5: this.$refs.pictureLine5.getChartImg(),
        });
        // try的作用 执行一个可能会抛出异常的操作,如果有异常,通过catch 接收eror后抛出,没有异常不执行catch
        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 }));
          throw error;
        }

        // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
        let out = doc.getZip().generate({
          type: "blob",
          mimeType:
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        });
        // 将目标文件对象保存为目标类型的文件,并命名
        // 也可以使用  模板字符串 加入变量, 让每一个导出的word文件都有自己的名字   `文件名${变量}.docx`
        saveAs(out, "自定义导出文件名称.docx");
      });
    }

图片处理 (图片通过echarts自带的导出函数导出)

    // 导出echarts图片,格式转换  该函数基本是一个固定写法,直接拿着用即可
    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;
    },

注意事项

需要注意因为接口而导致的异步问题,异步问题会导致数据没有填充上去,异步时确保拿到数据之后再执行导出操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1691358.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索AI写作工具:五款推荐

在现实生活中&#xff0c;除了专业的文字工作者&#xff0c;各行各业都避免不了需要写一些东西&#xff0c;比如策划案、论文、公文、讲话稿、总结计划……等等。而随着科技的进步&#xff0c;数字化时代的深入发展&#xff0c;AI已经成为日常工作中必不可少的工具了&#xff0…

智慧之选:开源与闭源大模型的未来探索

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

有一个3x4的矩阵,要求编写程序求出其中值最大的那个元素,以及其所在的行号和列号

解题思路&#xff1a; 先考虑解此问题的思路。从若干数中求最大数的方法很多&#xff0c;现在采用"打擂台"的算法。如果有若干人比武&#xff0c;先有一人站在台上&#xff0c;再上去一人与其交手&#xff0c;败者下台&#xff0c;胜者留在台上。第3个人再上…

selenium安装出错

selenium安装步骤&#xff08;法1&#xff09;&#xff1a; 安装失败法1 第一次实验&#xff0c;失败 又试了一次&#xff0c;失败 安装法2-失败&#xff1a; ERROR: Could not install packages due to an EnvironmentError: [WinError 5] 拒绝访问。: c:\\programdata\\a…

【C++题解】1697. 请输出n~1之间所有的整数

问题:1697. 请输出n~1之间所有的整数 类型&#xff1a;循环 题目描述&#xff1a; 从键盘读入一个整数 n &#xff0c;请输出 n∼1 之间所有的整数&#xff0c;每行输出 1 个。 比如&#xff0c;假设读入 n5 &#xff0c;输出结果如下&#xff1a; 5 4 3 2 1 输入&#xff1…

UE5 像素流与web 交互

总结下虚幻与网页的交互&#xff0c;这里将ue5 与js 交互传递参数记录下&#xff0c;其它的博主写的就是缺胳膊少腿的要么就是封闭收费&#xff0c;这个是在官方可以查询到。这里记录下&#xff1a; 点个关注不迷路&#xff1a; 具体的使用如下&#xff1a; 在你的游戏玩家类…

推荐几款新手学习编程的网站

免费在线开发平台 介绍一款编程平台&#xff0c;专为学生和开发者量身打造&#xff01;平台拥有近4000道编程题目&#xff0c;支持多种编程语言&#xff08;包括C、C、JavaScript、TypeScript、Go、Rust、PHP、Java、Ruby、Python3和C#&#xff09;&#xff0c;为您提供全面的学…

【Oracle篇】rman标准化全库备份策略:完整备份or增量备份(第三篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

YoloV8改进策略:蒸馏改进|CWDLoss|使用蒸馏模型实现YoloV8无损涨点|特征蒸馏

摘要 在本文中&#xff0c;我们成功应用蒸馏策略以实现YoloV8小模型的无损性能提升。我们采用了CWDLoss作为蒸馏方法的核心&#xff0c;通过对比在线和离线两种蒸馏方式&#xff0c;我们发现离线蒸馏在效果上更为出色。因此&#xff0c;为了方便广大读者和研究者应用&#xff…

Kubernetes Service 之原理与 ClusterIP 和 NodePort 用法

Kubernetes Service 之原理与 ClusterIP 和 NodePort 用法 Service 定义 在 Kubernetes 中&#xff0c;由于Pod 是有生命周期的&#xff0c;如果 Pod 重启它的 IP 可能会发生变化以及升级的时候会重建 Pod&#xff0c;我们需要 Service 服务去动态的关联这些 Pod 的 IP 和端口…

六个免费的AI制图网站的介绍

六个免费的AI制图网站的介绍 以下是六个免费的AI制图网站的介绍&#xff0c;包括官网、特点、缺点以及使用时的注意事项&#xff1a; 海鲸AI 官网&#xff1a;AI绘画创作平台 - 海鲸AI | 智能艺术生成器特点&#xff1a;支持PC和移动端&#xff0c;集成了Midjourney AI模型&am…

【Spring】SSM介绍_SSM整合

1、SSM介绍 1.1简介 SSM&#xff08;Spring SpringMVC MyBatis&#xff09;整合是一种流行的Java Web应用程序框架组合&#xff0c;它将Spring框架的核心特性、SpringMVC作为Web层框架和MyBatis作为数据访问层框架结合在一起。这种整合方式提供了从数据访问到业务逻辑处理再…

jmeter之测试计划

一、测试计划作用 测试计划是jmeter的默认控件所有线程组都是测试计划的下级控件测试计划可以配置用户自定义的变量测试计划可以配置线程组的串行或并行 二、查看界面 名称&#xff1a;可以修改自定义的名称注释&#xff1a;解释测试计划是用来做什么的用户自定义的变量&…

【Jmeter】使用Jmeter进行接口测试、跨线程组获取参数

Jmeter接口测试 Jmeter设置成中文实操练习-跨线程组提取参数&#xff0c;使用值HTTP请求默认值&HTTP信息头管理器 相信打算从事测试工程师的同学们&#xff0c;肯定对Jmeter是耳熟能详的。使用Jmeter可以进行接口测试、性能测试、压力测试等等&#xff1b;这个章节介绍如何…

在使用LabVIEW控制多个串口设备进行数据读取时,读取时间过长

在使用LabVIEW控制多个串口设备进行数据读取时&#xff0c;如果发现数据更新时间超过5秒&#xff0c;可以从以下几个方面进行分析和解决&#xff1a; 1. 串口配置与通信参数 确保每个串口的通信参数&#xff08;波特率、数据位、停止位、校验位等&#xff09;配置正确&#x…

百度软件测试面试经历,期望薪资27K

一面 1、 请为百度搜索框设计测试用例&#xff1f; 2、百度设计框上线前需要进行那些测试&#xff1f; 界面测试&#xff0c;功能测试&#xff0c;性能测试&#xff0c;安全性测试&#xff0c;易用性测试&#xff0c;兼容性测试&#xff0c;UI测试。 3、如何查看http状态码…

23. 【Java教程】接口

本小节我们将学习 Java 接口&#xff08;interface&#xff09;&#xff0c;通过本小节的学习&#xff0c;你将了解到什么是接口、为什么需要接口、如何定义和实现接口&#xff0c;以及接口的特点等内容。最后我们也将对比抽象类和接口的区别。 1. 概念 Java 接口是一系列方法的…

感恩父母的短视频:成都科成博通文化传媒公司

感恩父母的短视频&#xff1a;情深意重&#xff0c;温馨传递 在这个快节奏、信息化的时代&#xff0c;短视频以其独特的方式&#xff0c;迅速成为了人们表达情感、分享生活的重要工具。成都科成博通文化传媒公司而当我们把镜头对准父母&#xff0c;用短视频的形式记录下对他们…

【面试干货】矩阵对角线元素之和

【面试干货】矩阵对角线元素之和 1、实现思想2、代码实现 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、实现思想 创建一个3x3的二维数组来表示输入的矩阵。通过嵌套循环读取输入的矩阵元素&#xff0c;并将其保存到数组中。再次嵌套循…

云端升级,智能适配——LDR6282,USB-C接口显示器的最佳选择

华为MateView USB-C接口显示器技术深度解析与科普 随着科技的飞速发展&#xff0c;终端显示产品也迎来了全新的变革。在众多更新迭代中&#xff0c;华为MateView显示器凭借其独特的USB-C接口设计&#xff0c;为用户带来了前所未有的便捷体验。本文将带您深入探索这款显示器的技…