vue el-table 前端js实现导出数据为Excel

目录

一、背景描述

二、功能分析

三、详细开发

1.导出为excel

2.导出为cvs

四、总结


一、背景描述

有些业务常见,例如前端已经获取到表格的所有数据了,并且后端技术人员比较繁忙,总会提出前端分页,前端排序,甚至前端导出数据为excel的需求,所以这个文章就记录一下这个功能怎么实现。实现的功能:导出表格的数据为Excel或cvs,并且前端分页加排序。(不引入第三方库实现导出功能)


二、功能分析

不引入第三方库,所以就前端生成Excel并导出。

前端生成 Excel 文件的方式:首先获取表格数据内容,并对表头进行处理,以确保没有额外的空白单元格。然后,它构建了一个包含表格内容的 HTML 文件,其中包括 Excel 文件所需的一些元信息和样式。接下来,它将该 HTML 文件转换为 Blob 对象,然后通过创建链接并触发下载的方式,实现了文件的下载。

分页排序就比较简单了,只要复制一份表格数据,处理并展示这个数据就行,原始的数据可以用于导出数据。

如下:


三、详细开发

1.导出为excel

首先需要一个表格和导出按钮,如下:

            <el-col :span="4" >
              <el-button type="primary" @click="exportToExcel">导出</el-button>
            </el-col>

            <el-table
              :data="sortedAndPaginatedVerificationTableData"
              stripe
              border
              ref="tableRef"
              @sort-change="handleSortChange"
            >
              <el-table-column prop="age" label="年龄" width="150" sortable>
              </el-table-column>
              <el-table-column prop="status" label="状态" width="120" sortable>
              </el-table-column>
              <el-table-column
                prop="message"
                label="信息"
                sortable
              >
              </el-table-column>
            </el-table>

接着导出功能的实现,2种方式:

第一种,可忽略不看。

//导出Excel
    exportToExcel(){
      //第一种方式
      // 获取表格内容
      const excelContent = this.$refs.tableRef.$el.innerHTML;

      // 处理表头,确保没有额外的空白单元格
      const headerElement = document.createElement('div');
      headerElement.innerHTML = excelContent;
      const headerCells = headerElement.querySelectorAll('th');

      // 移除最后一个空单元格
      if (headerCells.length > 0) {
        const lastCell = headerCells[headerCells.length - 1];
        lastCell.parentNode.removeChild(lastCell);
      }

      // 构建 Excel 文件内容
      let excelFile = `
        <html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>
        <head>
        <!--[if gte mso 9]>
        <xml>
        <x:ExcelWorkbook>
        <x:ExcelWorksheets>
        <x:ExcelWorksheet>
        <x:Name>{worksheet}</x:Name>
        <x:WorksheetOptions>
        <x:DisplayGridlines/>
        </x:WorksheetOptions>
        </x:ExcelWorksheet>
        </x:ExcelWorksheets>
        </x:ExcelWorkbook>
        </xml>
        <![endif]-->
        <style>
        td{border: .5pt solid;}
        </style>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        </head>
        <body>
        ${headerElement.innerHTML}
        </body>
        </html>
      `;

      // 创建 Blob 对象
      const blob = new Blob([excelFile], { type: 'application/vnd.ms-excel' });

      // 创建链接并触发下载
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = '表格.xlsx'; // 设置默认文件名
      link.style.display = "none";
      document.body.appendChild(link);
      link.click();
      window.URL.revokeObjectURL(link.href);
      document.body.removeChild(link);

    }

 第二种:

//导出Excel
    exportToExcel(){
      //第二种方式
      
      // 获取表格数据
      const tableData = this.tableData;

      // 构建 Excel 文件内容
      let excelContent = `<html><head><meta charset="UTF-8"></head><body><table border="1">`;

      // 添加表头
      excelContent += '<tr>';
      for (const column of this.$refs.tableRef.columns) {
        if (column.property) {
          excelContent += `<th>${column.label}</th>`;
        }
      }
      excelContent += '</tr>';

      // 添加表格数据
      for (const row of tableData) {
        excelContent += '<tr>';
        for (const column of this.$refs.tableRef.columns) {
          if (column.property) {
            excelContent += `<td>${row[column.property]}</td>`;
          }
        }
        excelContent += '</tr>';
      }

      // 构建完整的 Excel 文件内容
      excelContent += '</table></body></html>';

      // 创建 Blob 对象
      const blob = new Blob([excelContent], { type: 'application/vnd.ms-excel' });

      // 创建链接并触发下载
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = '表格.xlsx'; // 设置默认文件名
      link.style.display = "none";
      document.body.appendChild(link);
      link.click();
      window.URL.revokeObjectURL(link.href);
    }

这里tableData是表格的原始数据,如果前端已经获取到表格的所有数据,就可以对整个数据进行导出,也就是推荐第二种方式,第一种方式可以对表格样式进行控制,但是数据是考虑当前页面的表格数据,也就是本页数据的导出,所以后来我摒弃了第一种方式,直接使用的第二种方式。

第二种方式的好处:

  1. 首先,它获取表格数据并遍历每一行,以构建 Excel 文件内容。

  2. 在构建表头时,它遍历了表格的列属性,以获取每一列的标签(label),并添加到表头中,不用控制表格过滤空白单元格,这是第一种的弊端。

2.导出为cvs

     let csvContent = "data:text/csv;charset=utf-8,";
      csvContent += "年龄,状态,信息\n"; // 添加表头

      // 添加数据行
      this.verificationTableData.forEach(row => {
        let csvRow = [];
        csvRow.push(row.age);
        csvRow.push(row.status);
        csvRow.push(row.message);
        csvContent += csvRow.join(",") + "\n";
      });

      // 创建下载链接
      const encodedUri = encodeURI(csvContent);
      const link = document.createElement("a");
      link.setAttribute("href", encodedUri);
      link.setAttribute("download", "data.csv");
      document.body.appendChild(link);

      // 触发点击下载
      link.click();
      document.body.removeChild(link);

 3.前端排序和分页

其实我已经写过不少这个功能,为何还要再提,只是因为我在写上面的功能时,无法沿用之前的写法能实现这个功能,所以记录一下。

sortColumn: '', // 存储当前排序的列
sortOrder: '', // 存储当前排序的顺序




computed: {
    sortedAndPaginatedVerificationTableData() {
      // console.log("sortedAndPaginatedVerificationTableData")
      let data = this.tableData.slice();
      if(data.length<1){
        return []
      }
      // console.log("sortedAndPaginatedVerificationTableData",'com')
      // 根据排序规则进行排序
      if (this.sortColumn && this.sortOrder) {
        data.sort((a, b) => {
          const valueA = a[this.sortColumn];
          const valueB = b[this.sortColumn];
          if (this.sortOrder === 'ascending') {
            if (valueA > valueB) return 1;
            if (valueA < valueB) return -1;
            return 0;
          } else {
            if (valueA > valueB) return -1;
            if (valueA < valueB) return 1;
            return 0;
          }
        });
      }
      // 如果需要分页,则进行分页操作
      if (this.page) {
        const startIndex = (this.page.page - 1) * this.page.limit;
        const endIndex = this.page.page * this.page.limit;
        data = data.slice(startIndex, endIndex);
      }
      return data;
    }
  },




 handleSortChange(column, order) {
      // 更新当前排序的列和顺序
      this.sortColumn = column.prop;
      this.sortOrder = column.order;
      console.log('change',column,order,this.sortColumn,this.sortOrder );
    },

四、总结

使用 HTML 表格和 Blob,将数据动态生成为 HTML 表格,然后通过 HTML5 的 Blob 和 URL.createObjectURL 方法来创建一个链接,最后让用户点击链接下载生成的 Excel 文件。虽然不是真正的 Excel 文件,但可以在大多数情况下满足导出需求。

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

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

相关文章

CycleGAN训练及测试过程细节记录

CycleGAN训练及测试过程细节记录 文章目录 关于训练关于测试 关于训练 1、训练前将数据配置好&#xff0c;并在Pycharm中写好配置信息 2、关于训练过程的参数配置在 options/train_options.py options/base_options.py batch_size&#xff1a;批大小 crop_size&#xff1a;…

Vue.js前端开发零基础教学(一)

目录 第一章 初识Vue.js 前言 开发的好处 一.前端技术的发展 什么是单页Web应用&#xff1f; 二. Vue的简介 三. Vue的特性 四. Vue的版本 五.常见的包管理 六.安装node环境 第一章 初识Vue.js 学习目标&#xff1a; 了解前端技术的发展 了解什么是Vue掌握使用方…

凡事不以规矩不成方圆,合同协议模板范本大全

一、资料描述 本套合同协议资料&#xff0c;大小18.42M&#xff0c;24个压缩文件。 二、资料目录 01-租赁合同.rar&#xff08;112个文件&#xff09; 02-装修协议.rar&#xff08;32个文件&#xff09; 03-转让或承包协议.rar&#xff08;32个文件&#xff09; 04-员工手…

羊大师揭秘,孩子适不适合喝羊奶?

羊大师揭秘&#xff0c;孩子适不适合喝羊奶&#xff1f; 羊奶&#xff0c;这个古老而珍贵的营养饮品&#xff0c;近年来在家长们中间逐渐走红。它以其独特的营养价值和口感受到了众多家庭的青睐。但是&#xff0c;面对市面上琳琅满目的羊奶产品&#xff0c;家长们常常陷入选择…

ViT如何支持变长序列(patches)输入?

问题&#xff1a;当增加输入图像的分辨率时&#xff0c;例如DeiT 从 224 到 384&#xff0c;一般来说会保持 patch size&#xff08;例如9&#xff09;&#xff0c;因此 patch 的数量 N 会发生了变化。那么视觉transformer是如何处理变长序列输入的? 回答&#xff1a; 在讨论…

MySQL的目录结构

安装目录 /usr/local/mysql数据目录 /usr/local/mysql/data配置目录 /usr/local/etc/my.cnf点击返回 MySQL 快速学习目录

【NLP】TF-IDF算法原理及其实现

&#x1f33b;个人主页&#xff1a;相洋同学 &#x1f947;学习在于行动、总结和坚持&#xff0c;共勉&#xff01; #学习笔记# 目录 01 TF-IDF算法介绍 02 TF-IDF应用 03 Sklearn实现TF-IDF算法 04 使用TF-IDF算法提取关键词 05 TF-IDF算法的不足 TF-IDF算法非常容易理…

matlab 基于小波变换的油气管道泄露信号检测

1、内容简介 略 71-可以交流、咨询、答疑 基于小波变换的油气管道泄露信号检测 去噪、小波变换、油气管道泄露、信号检测 2、内容说明 摘 要&#xff1a; 油气管道泄漏会造成严重危害&#xff0c;因此&#xff0c;亟需寻找一种能快速检测油气管道信号的技术。传统的 傅里…

Vue2(八):脚手架结构、render函数、ref属性、props配置项、mixin(混入)、插件、scoped样式

一、脚手架结构分析 crlc终止刚刚搭建的vue。 ├── node_modules ├── public │ ├── favicon.ico: 页签图标 │ └── index.html: 主页面 ├── src │ ├── assets: 存放静态资源 │ │ └── logo.png │ │── component: 存放组件 │ │ …

Gin框架 源码解析

https://zhuanlan.zhihu.com/p/136253346 https://www.cnblogs.com/randysun/category/2071204.html 这个博客里其他go的内容也讲的很好 启动 因为 gin 的安装教程已经到处都有了&#xff0c;所以这里省略如何安装&#xff0c; 建议直接去 github 官方地址的 README 中浏览安装…

【数据库基础增删改查】条件查询、分页查询

系列文章目录 &#x1f308;座右铭&#x1f308;&#xff1a;人的一生这么长、你凭什么用短短的几年去衡量自己的一生&#xff01; &#x1f495;个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C,自顶向下看Java-CSDN博客 ❤️相关文章❤️&#xff1a;清灵白羽 漾情天…

AI浸入社交领域,泛娱乐APP如何抓住新风口?

2023年是大模型技术蓬勃发展的一年&#xff0c;自ChatGPT以惊艳姿态亮相以来&#xff0c;同年年底多模态大模型技术在国内及全球范围内的全面爆发&#xff0c;即模型能够理解并生成包括文本、图像、视频、音频等多种类型的内容。例如&#xff0c;基于大模型的文本到图像生成工具…

Samtec科普 | 一文了解患者护理应用连接器

【摘要/前言】 通过医疗专业人士为患者提供护理的种种需求&#xff0c;已经不限于手术室与医院的各种安全状况。当今许多患者的护理都是在其他环境进行&#xff0c;例如医生办公室、健康中心&#xff0c;还有越来越普遍的住家。尤其是需要长期看护的患者&#xff0c;所需的科技…

Mysql数据库概念与安装

目录 一、数据库概述 1、数据库的基本概念 2、数据库管理系统&#xff08;DBMS&#xff09; 2.1 数据库管理系统概念 2.2 数据库管理系统工作模式 3、数据库系统&#xff08;DBS&#xff09; 3.1 数据库系统概念 3.2 数据库系统发展史 4、关系型数据库与非关系型数据库…

机器学习——终身学习

终身学习 AI不断学习新的任务&#xff0c;最终进化成天网控制人类终身学习&#xff08;LLL&#xff09;&#xff0c;持续学习&#xff0c;永不停止的学习&#xff0c;增量学习 用线上收集的资料不断的训练模型 问题就是对之前的任务进行遗忘&#xff0c;在之前的任务上表现不好…

【机器学习】无监督学习算法之:K均值聚类

K均值聚类 1、引言2、K均值聚类2.1 定义2.2 原理2.3 实现方式2.4 算法公式2.4.1 距离计算公式2.4.1 中心点计算公式 2.5 代码示例 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c; K均值聚类 我不懂&#xff0c;能不能给我讲一讲&#xff1f; 小鱼&#xff1a;行&#xf…

AI助手 - Fitten Code

前言 上一篇介绍了商汤AI编程小助手小浣熊 Raccoon&#xff0c;过程中又发现了另外一款国产AI编程助手&#xff0c;那就是本篇要介绍的非十科技出品的Fitten Code。 ​ Fitten Code 主打一个快&#xff1a;超高准确率、超快的响应速度。号称代码生成比GitHub Copilot 快两倍&am…

蓝桥杯模块综合——高质量讲解AT24C02,BS18B20,BS1302,AD/DA(PCF8591),超声波模块

AT24C02——就是一个存储的东西&#xff0c;可以给他写东西&#xff0c;掉电不丢失。 void EEPROM_Write(unsigned char * EEPROM_String,unsigned char addr , unsigned char num) {IIC_Start();IIC_SendByte(0xA0);IIC_WaitAck();IIC_SendByte(addr);IIC_WaitAck();while(nu…

奶牛均分

解法&#xff1a; 假设编号从左到右递增&#xff0c;奶牛每次只能去往左边的牛圈。因此等分最大奶牛数小于等于最右边牛圈奶牛数&#xff0c;不妨设数为k&#xff0c;那么a[i]>k&#xff0c;a[i-1]>2k。。。 做后缀和二分答案就可找到k #include<iostream> #inc…

字符串筛选排序 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 输入一个由n个大小写字母组成的字符串&#xff0c; 按照 ASCII 码值从小到大的排序规则&#xff0c;查找字符串中第 k 个最小ASCII 码值的字母(k>1) , 输出该…