前端导出word文件的多种方式、前端导出excel文件

文章目录

  • 纯前借助word模板端导出word文件 (推荐)
    • 使用模板导出
  • 前端通过模板字符串导出word文件
  • 前端导出 excel文件,node-xlsx导出文件,行列合并

纯前借助word模板端导出word文件 (推荐)

先看效果:
这是页面中的table
在这里插入图片描述
这是导出后的效果:
在这里插入图片描述

使用模板导出

需要的依赖:
npm 自行安装,需要看官网的具体参数自行去github上面找对应的参数

 	"docxtemplater": "^3.46.0",
    "pizzip": "^3.1.6",
    "jszip-utils": "^0.1.0",
    "file-saver": "^2.0.5",

具体代码:(先看word模板,在看代码,word中的变量和代码中 doc.setData() 是一一对应的)
在这里插入图片描述

<template>
  <div class="button-box">
    <a-space>
      <a-button type="danger" @click="downWord2">模板导出word文件</a-button>
    </a-space>
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, reactive, PropType, ref } from 'vue';
import { message } from 'ant-design-vue';
import moment from 'moment';
import { downloadPDF } from '../../../../utils/utils';
import { useTable } from './hooks/useTable';
import xlsx from 'node-xlsx';

import docxtemplater from 'docxtemplater';
import PizZip from 'pizzip';
import JSZipUtils from 'jszip-utils';
import { saveAs } from 'file-saver';

export default defineComponent({
  props: {
    /**
     * 基础数据
     */
    baseData: {
      type: Object as PropType<{
        taskId: string;
        barcodeId: string;
      }>,
      default: {},
    },
    /**
     * 样本名称
     */
    barcodeName: {
      type: String,
    },
  },

  setup(props) {
    let width = 100;
    const { barcodeName } = props;
    const { taskId, barcodeId } = props.baseData;
    const { tableConfig, tableConfigLeft, getDta } = useTable();



    onMounted(() => {
      barcodeName ? getDta(taskId, barcodeName) : '';
    });
    
    const tableValue = reactive({
      unit: '中国',
      date: undefined,
      sampleType: '你猜',
      people: '黄种人',
      name: '夜空',
      sex: '男',
      age: '25',
      work: '开发',
      id: '',
      jiance: '商品化试剂盒',
      date2: undefined,
    });

   
    const downWord2 = () => {
      let docxname = '导出word.docx';
      JSZipUtils.getBinaryContent('/test.docx', function (error: any, content: any) {
        // test.docx是模板(这里我放到public公共文件夹下面了)。我们在导出的时候,会根据此模板来导出对应的数据
        // 抛出异常
        if (error) {
          throw error;
        }

        // 创建一个PizZip实例,内容为模板的内容
        let zip = new PizZip(content);
        // 创建并加载docx templater实例对象
        let doc = new docxtemplater().loadZip(zip);
        // 设置模板变量的值  主要变量替换在这里
        doc.setData({
          name: tableValue.name,
          unit: tableValue.unit,
          date: moment(tableValue.date).format('YYYY-MM-DD'),
          sampleType: tableValue.sampleType,
          sex: tableValue.sex,
          age: tableValue.age,
        });

        try {
          // 用模板变量的值替换所有模板变量
          doc.render();
        } catch (error: any) {
          // 抛出异常
          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',
        });
        // 将目标文件对象保存为目标类型的文件,并命名
        saveAs(out, docxname);
      });
    };

    return {
      downWord2,
      getDta,
      tableConfig,
      tableConfigLeft,
      tableValue,
      downloadPDF,
      value4: ref('less'),
    };
  },
});
</script>

<style lang="less" scoped>

</style>

前端通过模板字符串导出word文件

包依赖:

 "file-saver": "^2.0.5",

代码

import FileSaver from 'file-saver';
import htmlDocx from "html-docx-js/dist/html-docx"
import { G } from '@/global';
const { rootUrl, rbacToken } = G;
let cycle_info1 = [
  {
    name: '事件类型',
    key: 'eventTypeName',
  },
  {
    name: '地点定位',
    key: 'locationAddress',
  },
  {
    name: '上报时间',
    key: 'reportTime',
  },
  {
    name: '人员姓名',
    key: 'reportUserName',
  },
  {
    name: '联系方式',
    key: 'reportUserPhone',
  },
]

const model = (reportInfoDetail: any, list: any, eventState: any) => {
  // console.log(reportInfoDetail, list, eventState);

  return (
    `
    <!DOCTYPE html>
      <html>

<head>
  <style>
    .MaxBox {
      padding: 0px 15px;
      overflow-y: auto;
      height: 50vh;
    }

    .fromBox {}

    .formTitle_first {
      color: #1c69f7;
      font-size: 23px;
      font-weight: bold;
      margin-bottom: 10px;
    }

    .formTitle_second {
      font-weight: bold;
      font-size: 16px;
      margin-bottom: 10px;
    }

    .formContent_box {
      margin-bottom: 5px;
    }

    .formContent_box_title {
      min-width: 60px;
    }

    .display_flex {
      display: flex;
    }
  </style>
</head>

<body>
  <div class="MaxBox">
    <div class="fromBox">
      <div class="formTitle_first">上报信息</div>
      <div class="formTitle_second">上报信息</div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title" >事件类型:</span>
        <span>${reportInfoDetail['eventTypeName']}</span>
      </div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title">地点定位:</span>
        <span>${reportInfoDetail['locationAddress']}</span>
      </div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title">上报时间:</span>
        <span>${reportInfoDetail['reportTime']}</span>
      </div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title">人员姓名:</span>
        <span>${reportInfoDetail['reportUserName']}</span>
      </div>
      <div class="formContent_box display_flex" style="display:flex">
        <span class="formContent_box_title">联系方式:</span>
        <span>${reportInfoDetail['reportUserPhone']}</span>
      </div>
    
      <div class="formTitle_second">图片附件</div>
      <div class="formContent_box">
        ${reportInfoDetail['picIds']?.map((res1: any, idx1: any) => {
      return `
        <img width='240' height='160' src="${rootUrl}/fyVolunteer/file/download/${res1}?rbacToken=${rbacToken}"
          style='margin-right:5px'
        />
        ${((idx1 + 1) % 2 == 0) ? `<br />` : ''}
        `
    })
    }
      </div>
      <div class="formTitle_second">事件描述</div>
      <div class="formContent_box">${reportInfoDetail['description']}</div>
    </div>
    ${reportInfoDetail.assignInfo.length != 0 ?
      `
      <div class="fromBox">
      <div class="formTitle_first">指派信息</div>
      <div class="formTitle_second  display_flex">指派信息</div>
      <div class="formContent_box">
        <div class="formContent_box_title">指派单位:
          ${reportInfoDetail.assignInfo.map((res: any, idx: any) => {
        return `
              <span style="margin-right:15px">
                ${res.departmentName}
              </span>
              `
      })
      }
        </div >
      </div >
      <div class="formContent_box  display_flex">
          <span class="formContent_box_title">指派时间:</span>
          <span>${!!reportInfoDetail?.assignInfo[0]?.assignTime ? reportInfoDetail?.assignInfo[0]?.assignTime : ""}</span>
      </div>
    </div>
      `: ''

    }  

    <div class="fromBox">
      <div class="formTitle_first">处置信息</div>
      ${reportInfoDetail.handleInfo.length != 0 ?
      reportInfoDetail.handleInfo.map((itm: any, idx: any) => {
        return `
        <div class="formTitle_second">单位${idx + 1}${itm['claimDepartmentName']}</div>
        <div class="formTitle_second">签收信息</div>
        <div class="formContent_box display_flex"
        style="width:32vw;justify-content: space-between;">
          <div>
            <span>签收单位:${itm['claimDepartmentName']}</span>
          </div>
          <div>
            <span>签收时间:${itm['claimTime']}</span>
          </div>
        </div >
        <div class="formTitle_second">图片附件</div>
        <div class="formContent_box">
          ${itm['handleTime'] != null ?
            itm['handlePicIds']?.map((res1: any, idx1: any) => {
              return `
          <img width="240" height="160"
            src="${rootUrl}/fyVolunteer/file/download/${res1}?rbacToken=${rbacToken}"
            style="margin-right:5px"
          />
          ${(idx1 + 1) % 2 == 0 ? `<br />` : ''}
          `
            }) : `<span style="color:#5558e8">无</span>`
          }
        </div>

        <div class="formTitle_second">处置描述</div>
        <div class="formContent_box">${itm.handleTime != null ? itm['handleDescription'] : `<span style="color:#5558e8">未上传处置</span>`}</div>

        <div class="formTitle_second">上报信息</div>
        <div class="formContent_box display_flex"
        style="width:32vw;justify-content: space-between;">
          <div>
            <span>上报单位:${itm['claimDepartmentName']}</span>
          </div>
          <div>
            <span>上报时间:${itm['handleTime'] != null ? itm['handleTime'] : ''}</span>
          </div>
        </div>
        <br/>
        `
      }) : '无数据'
    }
    </div >

    <div class="fromBox">
      <div class="formTitle_first">其他信息</div>

      <div class="formContent_box  display_flex">
        <span class="formContent_box_title">信息状态:</span>
        <span>
          ${list[eventState - 1].desc}
          ${reportInfoDetail?.finishTime != null ? reportInfoDetail?.finishTime : ''}
        </span>
    </div>
    <div class="formContent_box  display_flex">
      <span class="formContent_box_title">采纳状态:</span>
      <span>${reportInfoDetail.acceptInfo == null ? "未采纳" : `已采纳(${reportInfoDetail.acceptInfo.integral})`}</span>
    </div>
  </div>
  </div >
</body >
</html >
  `
  )
}

const loadFile = (info: any) => {
  let html = model(info.reportInfoDetail, info.list, info.eventState)
  let blob = new Blob([html], { type: "application/msword;charset=utf-8" });
  // let blob = htmlDocx.asBlob(html, { orientation: "landscape" });
  FileSaver.saveAs(blob, "信息管理文件.doc");
}


export {
  loadFile
};



前端导出 excel文件,node-xlsx导出文件,行列合并

导出效果:
在这里插入图片描述

需要的依赖: node-xlsx

    "node-xlsx": "^0.23.0",

代码:

    const downXlsx = () => {
      let data = [
        [1, 222, '', '', '', ''],
        ['', 2, 3, 4, 5, 6],
        ['', 2, 3, 4, 5, 6],
        ['', 2, 3, 4, 5, 6],
        ['', 2, 3, 4, 5, 6],
        [22, 2, 3, 4, 5, 6],
      ];

      // 行列合并规则  c:col 列   r:row 行
      const range0 = { s: { c: 0, r: 0 }, e: { c: 0, r: 4 } };
      const range1 = { s: { c: 1, r: 0 }, e: { c: 5, r: 0 } };
      const sheetOptions = {
        '!merges': [range0, range1],
        // cols 列宽大小
        '!cols': [{ wch: 5 }, { wch: 10 }, { wch: 15 }, { wch: 20 }, { wch: 30 }, { wch: 50 }],
      };
      //如果不需要格式,这里的sheetOptions可以省略不写
      let result = xlsx.build([{ name: 'sheet1', data }], { sheetOptions });
      const ab = Buffer.from(result, 'binary');
      const blob = new Blob([ab]);
      const blobUrl = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = blobUrl;
      a.download = '导出excel.xlsx';
      a.click();
      window.URL.revokeObjectURL(blobUrl);
    };

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HCIP-VLAN综合实验(VLAN的Access接口、Trunk接口、Hybrid 接口、dot1q封装,DHCP设置)

VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。每个VLAN是一个广播域&#xff0c;VLAN内的主机间通信就和在一个LAN内一样&#xff0c;而VLAN间则不能直接互通&#xff0c;这样&#…

2024环境工程、能源系统与化学材料国际会议(ICEEESCM 2024)

2024环境工程、能源系统与化学材料国际会议&#xff08;ICEEESCM 2024) 一、【会议简介】 2024环境工程、能源系统与化学材料国际会议&#xff08;ICEEESCM 2024)将于2024年在西安举行。会议将围绕环境工程、能源系统与化学材料等议题展开讨论&#xff0c;旨在为从事环境工程…

idea使用maven创建springboot项目

按照图片中的流程来&#xff0c;就可以创建springboot项目&#xff0c;我这个主要是想做一个JavaWeb项目 有用的话&#xff0c;点个小赞赞再走呀~

IPD MM流程之业务策略工具:安索夫矩阵

IPD市场管理流程&#xff0c;华为内部称为“MM流程”&#xff08;Market Management&#xff0c;MM&#xff09;。华为市场管理是通过对市场和细分市场的分析&#xff0c;制定细分市场的策略&#xff0c;形成商业计划&#xff0c;把商业计划落实在日常工作当中。MM流程其中一个…

【Django】执行查询—跨关系查询中的跨多值关联问题

跨多值查询 跨越 ManyToManyField 或反查 ForeignKey &#xff08;例如从 Blog 到 Entry &#xff09;时&#xff0c;对多个属性进行过滤会产生这样的问题&#xff1a;是否要求每个属性都在同一个相关对象中重合。 filter() 先看filter()&#xff0c;通过一个例子看&#xf…

【three.js】搭建本地静态服务器 查询API文档使用

目录 一、为什么要搭建本地静态服务器呢&#xff1f; 二、下载three.js文件包 三、vscode配置live-server插件 一、为什么要搭建本地静态服务器呢&#xff1f; 平时学习Three.js&#xff0c;如果你想预览代码3D效果、查询API文档等&#xff0c;咱们需要提供一个本地静态服务…

基于JAVA的快递投保管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 软件2.2 布局2.3 技术框架 三、功能模块3.1 保险类型模块3.2 快递管理模块3.3 保险订单模块 四、系统展示五、核心代码5.1 查询快递5.2 查询快递保险5.3 新增快递保险5.4 快递投保5.5 查询保险订单 六、免责说明 一、摘…

LVGL常用部件使用总结之图片部件

图片部件可用于显示图片&#xff0c;图片源可以是 C 语言数组格式的文件、二进制的.bin 文件以及图标字体。值得注意的是&#xff0c;图片部件要显示 BMP、JPEG 等格式的图片&#xff0c;则必须经过解码。 图片部件的组成部分仅有一个&#xff1a;主体&#xff08;LV_PART_MAIN…

硬盘坏了怎么把数据弄出来?数据恢复方法推荐

在数字化时代电脑硬盘中的数据承载着我们的工作成果、生活回忆和珍贵资料。然而一旦硬盘出现故障&#xff0c;数据的安全就变得岌岌可危。那么当电脑硬盘出现问题时&#xff0c;我们真的无法挽回那些重要数据了吗&#xff1f;答案是&#xff1a;不一定&#xff01;本文将为您介…

【Python】【函数】详解Python函数概念

1. 函数定义 函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现单一&#xff0c;或相关联功能的代码段。 函数能提高应用的模块性&#xff0c;和代码的重复利用率。你已经知道Python提供了许多内建函数&#xff0c;比如print()。但你也可以自己创建函数&#xf…

docker配置数据默认存储路径graph已过时,新版本中是data-root

错误信息 我在修改/etc/docker/daemon.json文件中&#xff0c;添加存储路径graph字段。然后sudo systemctl restart docker包如下错误&#xff1a;使用journalctl -xeu docker.service错误信息&#xff0c;发现不能匹配graph字段。 原因 我的docker版本&#xff1a; 在doc…

RocketMQ安装

这里写目录标题 mq服务端安装配置启动 mq管理界面安装配置启动 mq服务端 安装 RocketMQ下载地址 配置 ROCKETMQ_HOME D:\google-d\rocketmq-all-5.2.0-bin-release启动 # bin目录cmd输入 start mqnamesrv.cmdmq管理界面 安装 下载地址 配置 #修改rocketmq-console\src\…

简单数据类型和复杂数据类型

1. 简单数据类型 null是个特例: 2. 复杂数据类型 3. 堆和栈 注意&#xff1a; JavaScript 中是没有堆和栈的概念的&#xff0c;通过堆栈的概念可以更好的理解代码的一些执行方式&#xff0c;便于将来学习其他语言。 4. 简单数据类型传参 总结&#xff1a;简单数据类型传参传…

吉客云对接打通金蝶云星空销售单查询接口与销售出库新增接口

吉客云对接打通金蝶云星空销售单查询接口与销售出库新增接口 接入系统&#xff1a;吉客云 “吉客云”是一站式企业数字化解决方案系统&#xff0c;可实现业务、财务、办公、人事等一体化管理。相对于传统多套软件系统的集成方案&#xff0c;“吉客云”具有业务流程更流畅&#…

2024年新提出的算法|鹦鹉优化器(Parrot optimizer):算法及其在医疗问题中的应用

本期介绍一种基于训练后鹦鹉关键行为的高效优化方法——鹦鹉优化器(Parrot Optimizer, PO)。该成果于2024年2月发表在中科院2区top SCI期刊Computers in Biology and Medicine&#xff08;IF7.7&#xff09; 1、简介 鹦鹉优化器&#xff08;PO&#xff09;是一种受训练有素的…

政府采购标书制作的要点解析

导语&#xff1a;政府采购是政府为满足公共利益&#xff0c;按照法定程序和标准&#xff0c;通过招标、竞争性谈判等方式&#xff0c;购买商品、工程和服务的行为。标书作为政府采购活动中的重要文件&#xff0c;其制作质量直接影响到项目的顺利进行。本文将围绕政府采购标书制…

UE学习笔记--解决滚轮无法放大蓝图、Panel等

我们发现有时候创建蓝图之后&#xff0c;右上角的缩放是1&#xff1a;1 但是有时候我们可能需要放的更大一点。 发现一直用鼠标滚轮像上滚动&#xff0c;都没有效果。 好像最大只能 1&#xff1a;1. 那是因为 UE 做了限制。如果希望继续放大&#xff0c;我们可以按住 Ctrl 再去…

【golang】go module依赖的git tag被覆盖 如何处理 | 因测试产生大量的git tag 如何清除 最佳实践

一、场景 当我们把本地和远程git仓库的 tag全部删除&#xff0c;我们另外的项目依赖于这个被删除tag无法更新版本 如何处理&#xff1f; 如上图&#xff1a; 这里我创建了一个 v0.0.1 的tag&#xff0c;然后删除了这个tag&#xff0c;然后又创建了一个新的 v0.0.1的tag&#xf…

Linux进程管理:(二)进程调度原语

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 进程调度的概念比较简单&#xff0c…

专为大模型训练优化,百度集合通信库 BCCL 万卡集群快速定位故障

1 集合通信对分布式训练至关重要 在分布式训练中&#xff0c;每一块 GPU 只负责处理部分模型或者数据。集群中不同 GPU 之间通过集合通信的方式&#xff0c;完成梯度同步和参数更新等操作&#xff0c;使得所有 GPU 能够作为一个整体加速模型训练。 如果有一块 GPU 在集合通…