前端导出多级表头

2023-11-20

前端导出多级表头

今天在技术交流群里面看到有人问到了这一块,我之前看过一些关于这样的代码,我就直接给他上了代码,自己又重新练习里一遍

这是结合elementUI来写的一个表格。

先看一下练习的是这样的效果
在这里插入图片描述

首先还是要安装依赖

npm install xlsx file-saver -S
npm install script-loader -S -D

直接上代码
1、需要一个Export2Excel.js文件

/* eslint-disable */
import { saveAs } from 'file-saver'
import XLSX from 'xlsx'

function generateArray(table) {
  var out = [];
  var rows = table.querySelectorAll('tr');
  var ranges = [];
  for (var R = 0; R < rows.length; ++R) {
    var outRow = [];
    var row = rows[R];
    var columns = row.querySelectorAll('td');
    for (var C = 0; C < columns.length; ++C) {
      var cell = columns[C];
      var colspan = cell.getAttribute('colspan');
      var rowspan = cell.getAttribute('rowspan');
      var cellValue = cell.innerText;
      if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;

      //Skip ranges
      ranges.forEach(function (range) {
        if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
          for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
        }
      });

      //Handle Row Span
      if (rowspan || colspan) {
        rowspan = rowspan || 1;
        colspan = colspan || 1;
        ranges.push({
          s: {
            r: R,
            c: outRow.length
          },
          e: {
            r: R + rowspan - 1,
            c: outRow.length + colspan - 1
          }
        });
      };

      //Handle Value
      outRow.push(cellValue !== "" ? cellValue : null);

      //Handle Colspan
      if (colspan)
        for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
    }
    out.push(outRow);
  }
  return [out, ranges];
};

function datenum(v, date1904) {
  if (date1904) v += 1462;
  var epoch = Date.parse(v);
  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}

function sheet_from_array_of_arrays(data, opts) {
  var ws = {};
  var range = {
    s: {
      c: 10000000,
      r: 10000000
    },
    e: {
      c: 0,
      r: 0
    }
  };
  for (var R = 0; R != data.length; ++R) {
    for (var C = 0; C != data[R].length; ++C) {
      if (range.s.r > R) range.s.r = R;
      if (range.s.c > C) range.s.c = C;
      if (range.e.r < R) range.e.r = R;
      if (range.e.c < C) range.e.c = C;
      var cell = {
        v: data[R][C]
      };
      if (cell.v == null) continue;
      var cell_ref = XLSX.utils.encode_cell({
        c: C,
        r: R
      });

      if (typeof cell.v === 'number') cell.t = 'n';
      else if (typeof cell.v === 'boolean') cell.t = 'b';
      else if (cell.v instanceof Date) {
        cell.t = 'n';
        cell.z = XLSX.SSF._table[14];
        cell.v = datenum(cell.v);
      } else cell.t = 's';

      ws[cell_ref] = cell;
    }
  }
  if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
  return ws;
}

function Workbook() {
  if (!(this instanceof Workbook)) return new Workbook();
  this.SheetNames = [];
  this.Sheets = {};
}

function s2ab(s) {
  var buf = new ArrayBuffer(s.length);
  var view = new Uint8Array(buf);
  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
  return buf;
}

export function export_table_to_excel(id) {
  var theTable = document.getElementById(id);
  var oo = generateArray(theTable);
  var ranges = oo[1];

  /* original data */
  var data = oo[0];
  var ws_name = "SheetJS";

  var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data);

  /* add ranges to worksheet */
  // ws['!cols'] = ['apple', 'banan'];
  ws['!merges'] = ranges;

  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name);
  wb.Sheets[ws_name] = ws;

  var wbout = XLSX.write(wb, {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  });

  saveAs(new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  }), "test.xlsx")
}

export function export_json_to_excel({
  multiHeader = [],
  header,
  data,
  filename,
  merges = [],
  autoWidth = true,
  bookType = 'xlsx'
} = {}) {
  /* original data */
  filename = filename || 'excel-list'
  data = [...data]
  data.unshift(header);

  for (let i = multiHeader.length - 1; i > -1; i--) {
    data.unshift(multiHeader[i])
  }

  var ws_name = "SheetJS";
  var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data);

  if (merges.length > 0) {
    if (!ws['!merges']) ws['!merges'] = [];
    merges.forEach(item => {
      ws['!merges'].push(XLSX.utils.decode_range(item))
    })
  }

  if (autoWidth) {
    /*设置worksheet每列的最大宽度*/
    const colWidth = data.map(row => row.map(val => {
      /*先判断是否为null/undefined*/
      if (val == null) {
        return {
          'wch': 10
        };
      }
      /*再判断是否为中文*/
      else if (val.toString().charCodeAt(0) > 255) {
        return {
          'wch': val.toString().length * 2
        };
      } else {
        return {
          'wch': val.toString().length
        };
      }
    }))
    /*以第一行为初始值*/
    let result = colWidth[0];
    for (let i = 1; i < colWidth.length; i++) {
      for (let j = 0; j < colWidth[i].length; j++) {
        if (result[j]['wch'] < colWidth[i][j]['wch']) {
          result[j]['wch'] = colWidth[i][j]['wch'];
        }
      }
    }
    ws['!cols'] = result;
  }

  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name);
  wb.Sheets[ws_name] = ws;

  var wbout = XLSX.write(wb, {
    bookType: bookType,
    bookSST: false,
    type: 'binary'
  });
  saveAs(new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  }), `${filename}.${bookType}`);
}


2、下面就是HTML和JS部分

<template>
  <div>
    <el-button type="primary" @click.native="outExcel">导出</el-button>
    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="date" label="日期" width="150"> </el-table-column>
      <el-table-column label="配送信息">
        <el-table-column prop="name" label="姓名" width="120">
        </el-table-column>
        <el-table-column label="地址">
          <el-table-column prop="province" label="省份" width="120">
          </el-table-column>
          <el-table-column prop="city" label="市区" width="120">
          </el-table-column>
          <el-table-column prop="address" label="地址" width="300">
          </el-table-column>
          <el-table-column prop="zip" label="邮编" width="120">
          </el-table-column>
        </el-table-column>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          date: "2016-05-03",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区",
          zip: 200333,
        },
        {
          date: "2016-05-02",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区",
          zip: 200333,
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区",
          zip: 200333,
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区",
          zip: 200333,
        },
        {
          date: "2016-05-08",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区",
          zip: 200333,
        },
      ],
    };
  },
  methods: {
    outExcel() {
        //../untils/Export2Excel 这个是根据你自己存放Export2Excel.js文件的路径来写的
      import("../untils/Export2Excel").then((excel) => {
        const multiHeader = [
          ["日期", "配送信息", "", "", "", ""],//第一行表头
          ["", "姓名", "地址", "", "", ""],//第二行表头
        ];
        const tHeader = ["", "", "省份", "市区", "地址", "邮编"]; //最后一行的表头
        const filterVal = [
          "date",
          "name",
          "province",
          "city",
          "address",
          "zip",
        ];
        const list = this.tableData; //这个是你循环数据到页面上的的变量名
        const data = this.formatJson(filterVal, list);
        const merges = ["A1:A3", "B1:F1", "B2:B3", "C1:F1","C2:F2"];
        excel.export_json_to_excel({
          multiHeader,
          header: tHeader,
          merges,
          data,
          filename: this.filename,
          autoWidth: this.autoWidth,
          bookType: this.bookType,
        });
      });
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map((v) =>
        filterVal.map((j) => {
          if (j === "timestamp") {
            return v[j];
          } else {
            return v[j];
          }
        })
      );
    },
  },
};
</script>

<style>
</style>

以上就是前端导出多表头的代码。

还有一点需要注意的是const merges = [“A1:A3”, “B1:F1”, “B2:B3”, “C1:F1”,“C2:F2”];

这是根据你表头在excel里面需要合并的行数和列数,根据自己的需求来写merges里面的数据,如果不懂得请看下面的效果图上的标注。

在这里插入图片描述

以上就是多级表头导出的代码和注意的点,若有不懂的地方欢迎来打扰。希望可以帮助到大家!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前端导出多级表头 的相关文章

  • 为什么 Excel 有时会在工作表名称中添加 $?

    我有时但并非总是发现 Excel 会放置一个 位于工作表名称末尾 但在 Excel 中看不到 只有在尝试使用 C 将其导入 SQL Server 时才可见 我遇到过很多不同的情况 它保留了原始工作表 但也创建了第二个空的 隐藏 工作表 其中
  • 有没有任何方法可以使用 openpyxl 获取 .xlsx 工作表中存在的行数和列数?

    有没有任何方法可以使用 openpyxl 获取 xlsx 工作表中存在的行数和列数 在xlrd中 sheet ncols sheet nrows 将给出列数和行数 openpyxl中有这样的方法吗 给定一个变量sheet 可以通过以下方式之
  • Excel VBA - 循环文件夹中的文件、复制范围、粘贴到此工作簿中

    我有 500 个包含数据的 Excel 文件 我会将所有这些数据合并到一个文件中 实现此目标的任务列表 我想循环遍历文件夹中的所有文件 打开文件 复制此范围 B3 I102 将其粘贴到活动工作簿的第一张工作表中 重复但在下面粘贴新数据 我已
  • 检查所选单元格是否在特定范围内

    我正在使用 C 创建 Excel 加载项 如何检查选定的 或代码中范围表示的单元格 是否在特定范围内 例如如何检查单元格 P 5 是否在 A 1 Z 10 范围内 Use Application Intersect 像这样 在VBA中 Su
  • VBA 代码中的 Excel 公式

    所以 在 Sheet1 中 我有一些名称的基础 它看起来像这样 在 Sheet2 中 我正在使用 Sheet1 中的这些名称 我这样做的方式是在 A 列中输入代码值 在 B 列中输入名称 在 C 列中输入姓氏 看起来像这样 我已经用公式完成
  • 有没有办法将 Excel 单元格条目转换为一致的日期和时间格式?

    我正在处理雨量计数据记录器生成的 csv 文件中的一些雨量计数据 我发现日期和时间的记录不一致 以以下两种格式之一交替显示 Format 1 mm dd yyyy hh mm 24 hour clock or Format 2 mm dd
  • Range.End() 困惑

    我有一个关于 VBA 中 Range End 属性的一般性问题 我已经阅读了有关该房产的信息here http msdn microsoft com en us library bb221181 aspx 但我还是很困惑 例子 With w
  • 拆分具有多行文本和单行文本的行

    我试图弄清楚如何拆分数据行 其中行中的 B C D 列包含多行 而其他列不包含多行 我已经弄清楚如何拆分多行单元格 如果我将这些列复制到新工作表中 手动插入行 然后运行下面的宏 仅适用于 A 列 但我在编码时迷失了休息 Here s wha
  • 强力查询历年产品利润对比

    我有一个数据集 其中包含公司 产品 利润和年份 公司每年都会销售少量产品并获得利润 公司没有必要在明年销售相同的产品 他们可能会省略以前的产品并添加新的少量产品 我只想对两年的产品进行逐个比较 如下所示 我的数据集是 Company Pro
  • 你将如何开始自动化我的工作? - 第2部分

    后续这个问题 https stackoverflow com questions 2796128 how would you start automating my job 在经历了第一波进货 9 小时的复制 粘贴 后 我现在相信我已经满足
  • 运行时错误“1004”:对象“_Global”的方法“Range”失败

    我在使用 Excel 时遇到问题 有一个生成参考号的表单 但是当我尝试生成参考号时 它有一条错误消息 运行时错误 1004 对象 Global 的方法 Range 失败 当我点击 调试 按钮时 它显示的代码如下 它突出显示代码第 4 行的错
  • 运行时错误“1004”:无法获取 WorksheetFunction 类的 Combin 属性

    我在 Excel 2013 的工作簿中有 VBA 函数 可以根据泊松分布计算 p 值 当 的时候events下面代码中的变量超过 1029 我得到运行时错误 1004 无法获取 WorksheetFunction 类的 Combin 属性
  • 如何将 HTML 表格导出为 .xlsx 文件

    我有一个关于导出的问题HTML表格 as an xlsx文件 我做了一些工作 现在我可以将其导出为xls 但我需要将其导出为xlsx 这是我的 jsFiddle https jsfiddle net 272406sv 1 https jsf
  • 使用 MemoryStream 创建 Open XML 电子表格时的 Excel 和“不可读内容”

    使用 Open XML SDK v2 0 创建 Excel 电子表格时 我们的 Excel 输出最初可以成功运行几个月 最近Excel 所有版本 开始抱怨 Excel在 zot xlsx 中发现不可读的内容 是否要恢复此工作簿的内容 我们正
  • 将 Python Selenium 输出写入 Excel

    我编写了一个脚本来从在线网站上抓取产品信息 目标是将这些信息写入 Excel 文件 由于我的Python知识有限 我只知道如何在Powershell中使用Out file导出 但结果是每个产品的信息都打印在不同的行上 我希望每种产品都有一条
  • MS Access 中的舍入

    VBA Access 中舍入的最佳方法是什么 我目前的方法是利用Excel方法 Excel WorksheetFunction Round 但我正在寻找一种不依赖Excel的方法 请注意 VBA Round 函数使用 Banker 舍入 将
  • 在 VBA 中按键对字典进行排序

    我使用 VBA 创建了一个字典CreateObject Scripting Dictionary 将源单词映射到要在某些文本中替换的目标单词 这实际上是为了混淆 不幸的是 当我按照下面的代码进行实际替换时 它将按照源单词添加到字典中的顺序替
  • 如何使用 Excel Interop 获取筛选行的范围?

    我正在为我的项目使用 Excel Interop 程序集 如果我想使用自动过滤器 那么可以使用 sheet UsedRange AutoFilter 1 SheetNames 1 Microsoft Office Interop Excel
  • 如何禁用 openpyxl 表中的自动过滤器?

    当我使用 openpyxl 创建表时 它默认在所有列上添加自动过滤器 使用中提供的示例可以重现该行为文档 https openpyxl readthedocs io en stable worksheet tables html 我想显示没
  • Excel VBA 导出到文本文件。需要删除空行

    我有一个工作簿 使用以下脚本将其导出到文本文件 它工作正常 但是当我打开文本文件时 末尾总是有一个空行 这导致我在生成此文本文件后运行的另一个脚本出现问题 有关如何从导出中删除空行的任何帮助 Code Sub Rectangle1 Clic

随机推荐

  • 华硕T100HA鼠标乱跳及点击问题解决

    从入手此平板开始就一直有此问题 一直没有解决 今天正好装系统 就顺便解决此问题 一开始打算给这个平板安装Win7 8 网上说装了之后驱动不适配 就此放弃 然后 将系统恢复出厂设置了 然后问题依然在 在网上一直找啊找 终于在百度帖吧里找到问题
  • 人工智能概念

    人工智能概念 人工智能就是用人工方法在机器 计算机 上实现的智能 或称机器智能 即是研究如何用计算机来表示和执行人类的智能活动 以模拟人脑所从事的推理 学习 思考和规划等思维活动 并解决需要人类的智力才能处理的复杂问题 如医疗诊断 管理决策
  • 两个任意长度的长整数相乘(华为oj,C++)

    pre class cpp include oj h include pre
  • 【Android系统蓝牙开发】蓝牙基础知识-蓝牙核心系统架构

    什么是蓝牙 在开启基于蓝牙Spec v5 2的学习前 我们先了解下什么是蓝牙 蓝牙在我们日常生活中又存在哪些实际应用呢 蓝牙无线技术是一种短距离无线通信系统 其核心特性主要是以下三点 robustness 鲁棒性 抗干扰能力强 Low po
  • Python入门—— MySQL-python模块

    MySQL python模块 MySQLdb Python 标准数据库接口为 Python DB API Python DB API为开发人员提供了数据库应用编程接口 可以访问Python数据库接口及API查看详细的支持数据库列表 不同的数
  • Hadoop3 启动服务,提示:Attempting to operate on hdfs namenode as root

    在刚刚安装Hadoop3 环境上 启动Hadoop3 给出如下提示信息 Attempting to operate on hdfs namenode as root 翻译 尝试使用root 账户去操作hdfs namenode 造成原因 缺
  • IEEE 1588-PTP简介

    1 PTP简介 网络测控系统精确时钟同步协议PTP Precision Time Protocol 是一种对标准以太网终端设备进行时间和频率同步的协议 也称为IEEE 1588 简称为1588 1588分为1588v1和1588v2两个版本
  • 树莓派4B安装详细教程,从零开始!

    树莓派4B安装详细教程 从零开始 前言 一 准备材料 1 硬件材料 2 软件材料 二 安装步骤 1 格式化SD卡 2 安装系统 三 安装完成 前言 提示 本文详细介绍树莓派4B的安装流程 适合刚入手树莓派的同学 认为我写的好的同学希望点赞关
  • xxx-0.0.1-SNAPSHOT.jar中没有主清单属性

    添加如下配置即可
  • 算法通关村——二分查找在寻找数组峰顶中的应用

    题目 在数组i的某个位置i 开始 从 0 到 i 都是递增的 从 i 1 都是递减的 请你找到这个最高点 方法一 使用线性遍历实现 分析 最高点如果存在 需要满足arr i 1 lt arr i gt arr i 1 又因为题目说了0到i就
  • 史上最全的Android面试题集锦

    前言 很多人面试之前 可能没有在互联网公司工作过或者说工作过但年头较短 不知道互联网公司技术面试都会问哪些问题 再加上可能自己准备也不充分 去面试没几个回合就被面试官几个问题打蒙了 最后以惨败收场 下述是我收录整理的Android面试题汇总
  • 解决Photoshop无法完成请求,因为找到不知名的或无效的JPEG标识符类型问题

    在我将用微信Alt A截的图到Photoshop的时候出现无法完成请求 因为找到不知名的或无效的JPEG标识符类型问题 如下图 解决办法是 右击图片 用画图打开图片 将图片另存为jpg格式或者png格式即可 再次导入即可成功 具体原因不详
  • 2021年10月中旬—字节AI LAB NLP算法面试题(一)

    问题一 bert的架构是什么 目标是什么 输入包括了什么 三个embedding输入是怎么综合的 Bert的结构主要是Transformer的encoder部分 其中Bert base有12层 输出维度为768 参数量为110M Bert
  • 人工智能-10种机器学习常见算法

    机器学习是目前行业的一个创新且重要的领域 今天 给大家介绍机器学习中的10种常见的算法 希望可以帮助大家适应机器学习的世界 1 线性回归 线性回归 Linear Regression 是目前机器学习算法中最流行的一种 线性回归算法就是要找一
  • 因果推断:因果表征学习的CV落地

    作者 Ostrich 单位 阿里巴巴算法工程师 研究方向 自然语言处理 搜索算法 本文主要梳理因果推断与机器学习相结合的一些比较新的工作思路 也是尝试回答自己在学习因果推断基础知识时的一些疑问 突然 被广泛谈及的因果可以以什么样的方式落地
  • 【BS】compilation debug=true targetFramework=4.0 无法识别的属性“targetFramework”

    一 背景 今天在发布网站的时候遇到这个问题 compilation debug true targetFramework 4 0 无法识别的属性 targetFramework 系统是师哥新做的windows server 2008 图一
  • 【vue】前端下载文件自定义文件名称

    下载文件自定义文件名称 文件下载名称不想和后端提供的URL一样怎么办呢 1 首先给按钮去绑定一个事件 2 正常我们的下载处理方式 3 自定义下载的文件名字 文件下载名称不想和后端提供的URL一样怎么办呢 1 首先给按钮去绑定一个事件 按钮的
  • 微信小程序第六篇:元素吸顶效果实现

    系列文章传送门 微信小程序第一篇 自定义组件详解 微信小程序第二篇 七种主流通信方法详解 微信小程序第三篇 获取页面节点信息 微信小程序第四篇 生成图片并保存到手机相册 微信小程序第五篇 页面弹出效果及共享元素动画 话不多说 先看效果 这种
  • ElasticSearch ected map for property [fields] on field [subject_id] but got a class java.lang

    ElasticSearch的聚类时出现fielddata true Expected map for property fields on field subject id but got a class java lang String
  • 前端导出多级表头

    前端导出多级表头 今天在技术交流群里面看到有人问到了这一块 我之前看过一些关于这样的代码 我就直接给他上了代码 自己又重新练习里一遍 这是结合elementUI来写的一个表格 先看一下练习的是这样的效果 首先还是要安装依赖 npm inst