原生js用Export2Excel导出excel单级表头和多级表头数据方式实现
原生js用Export2Excel导出excel单级表头和多级表头数据方式实现
- 原生js用Export2Excel导出excel单级表头和多级表头数据方式实现
- HTML文件导入需要的文件
- HTML文件中实现导出函数
- HTML总代码实现汇总(直接复制代码,注意js引入路径)
原生js用Export2Excel导出excel单级表头和多级表头数据方式实现
因为项目框架的原因,不是使用纯vue开发的,所以用不了import的方式导入 file-saver 和 xlsx 的三方插件包去实现,索性我就把这两个文件下载本地,然后在HTML使用 script 标签的方式来实现。下面是具体实现方式:
HTML文件导入需要的文件
1、新建文件夹 命名为js,把对应的js文件放到里面,在js文件同级新建个表格导出.html 文件;
2、这里我用到了三个文件:FileSaver.min.js、xlsx.full.min.js、Export2Excel.js
3、注意其中的Export2Excel.js 是需要自己写的,其他两个文件去对应的GitHub地址下载即可,如果找不到可以评论区聊我,我看到可以私发你,这个Export2Excel.js 文件代码我粘贴在文章里面,直接复制使用,如下:
/* eslint-disable */
// 注意html中script js不能直接使用import方式导入文件, 需要把这两个js文件下载后,通过script方式加载进去
// 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.innerTextif (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue//Skip rangesranges.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 Spanif (rowspan || colspan) {rowspan = rowspan || 1colspan = colspan || 1ranges.push({s: {r: R,c: outRow.length},e: {r: R + rowspan - 1,c: outRow.length + colspan - 1}})};//Handle ValueoutRow.push(cellValue !== "" ? cellValue : null)//Handle Colspanif (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 += 1462var 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 = Rif (range.s.c > C) range.s.c = Cif (range.e.r < R) range.e.r = Rif (range.e.c < C) range.e.c = Cvar cell = {v: data[R][C]}if (cell.v == null) continuevar 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) & 0xFFreturn buf
}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] = wsvar wbout = XLSX.write(wb, {bookType: 'xlsx',bookSST: false,type: 'binary'})saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
}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] = wsvar wbout = XLSX.write(wb, {bookType: bookType,bookSST: false,type: 'binary'})saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), `${filename}.${bookType}`)
}
HTML文件中实现导出函数
<script>console.log(XLSX) // 打印看看 XLSXconsole.log(FileSaver) // 打印看看 FileSaverconsole.log(export_json_to_excel) // 打印看看export_json_to_excel 方法function downLoad() {let arr = [{sno: 1000,username: "fqniu",gender: "男",age: 27,card: "4****************7"}, {sno: 1001,username: "fqniu1",gender: "男",age: 27,card: "4****************8"},{sno: 1002,username: "fqniu2",gender: "男",age: 27,card: "4****************9"}]// 单级表格const tHeader = ["编号", "姓名", "性别", "年龄", "身份证号"]const filterVal = ["sno", "username", "gender", "age", "card"]const list = arrconst data = formatJson(filterVal, list)export_json_to_excel({header: tHeader,data,filename: "单级表格",autoWidth: true,bookType: "xlsx",})}// 多级表头function downLoad1() {let arr1 = [{date: '2024-08-17',num1: '1',count1: '10',num2: '11',count2: '100',num3: '111',count3: '1000',total: '1110',},{date: '2024-08-18',num1: '2',count1: '20',num2: '22',count2: '200',num3: '222',count3: '2000',total: '2220',},{date: '2024-08-19',num1: '3',count1: '30',num2: '33',count2: '300',num3: '333',count3: '3000',total: '3330',}]let filterVal1 = ['date', 'num1', 'count1', 'num2', 'count2', 'num3', 'count3', 'total']const data1 = formatJson(filterVal1, arr1)export_json_to_excel({multiHeader: [['日期', '上期结存', '', '本期结存', '', '下期结存', '', '总数']],header: ['', '数量', '金额', '数量', '金额', '数量', '金额', ''], //表头 必填data: data1, //具体数据 必填filename: '多级表头的表格',// 要合并的单元格merges: ['A1:A2', 'B1:C1', 'D1:E1', 'F1:G1', 'H1:H2'],autoWidth: true,bookType: 'xlsx',})}function formatJson(filterVal, jsonData) {return jsonData.map((v) =>filterVal.map((j) => {if (j === "timestamp") {return parseTime(v[j])} else {return v[j]}}))}</script>
导出的Excel文件内容截图如下:
单级表头效果
多级级表头效果
注意点:
导出多级表头首先要理解,单元格合并规则:
日期 所占单元格为 A1:A3
配送信息 所占单元格为 B1:F1
姓名 所占单元格为 B2:B3
然后依次类推即可
注:图片引用网络,仅用于学习分享
HTML总代码实现汇总(直接复制代码,注意js引入路径)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script src="./js/FileSaver.min.js"></script><script src="./js/xlsx.full.min.js"></script><script src="./js/Export2Excel.js"></script><script>console.log(XLSX)console.log(FileSaver)console.log(export_json_to_excel)function downLoad() {let arr = [{sno: 1000,username: "fqniu",gender: "男",age: 27,card: "4****************7"}, {sno: 1001,username: "fqniu1",gender: "男",age: 27,card: "4****************8"},{sno: 1002,username: "fqniu2",gender: "男",age: 27,card: "4****************9"}]// 单级表格const tHeader = ["编号", "姓名", "性别", "年龄", "身份证号"]const filterVal = ["sno", "username", "gender", "age", "card"]const list = arrconst data = formatJson(filterVal, list)export_json_to_excel({header: tHeader,data,filename: "单级表格",autoWidth: true,bookType: "xlsx",})}// 多级表头function downLoad1() {let arr1 = [{date: '2024-08-17',num1: '1',count1: '10',num2: '11',count2: '100',num3: '111',count3: '1000',total: '1110',},{date: '2024-08-18',num1: '2',count1: '20',num2: '22',count2: '200',num3: '222',count3: '2000',total: '2220',},{date: '2024-08-19',num1: '3',count1: '30',num2: '33',count2: '300',num3: '333',count3: '3000',total: '3330',}]let filterVal1 = ['date', 'num1', 'count1', 'num2', 'count2', 'num3', 'count3', 'total']const data1 = formatJson(filterVal1, arr1)export_json_to_excel({multiHeader: [['日期', '上期结存', '', '本期结存', '', '下期结存', '', '总数']],header: ['', '数量', '金额', '数量', '金额', '数量', '金额', ''], //表头 必填data: data1, //具体数据 必填filename: '多级表头的表格',// 要合并的单元格merges: ['A1:A2', 'B1:C1', 'D1:E1', 'F1:G1', 'H1:H2'],autoWidth: true,bookType: 'xlsx',})}function formatJson(filterVal, jsonData) {return jsonData.map((v) =>filterVal.map((j) => {if (j === "timestamp") {return parseTime(v[j])} else {return v[j]}}))}</script><div id="box">点击下载单级表格</div><div id="box1">点击下载多级表格</div><script>let box = document.getElementById('box')box.onclick = () => {downLoad()}let box1 = document.getElementById('box1')box1.onclick = () => {downLoad1()}</script></body>
</html>
以上就是我使用原生js用Export2Excel导出excel单级表头和多级表头数据方式实现的方式,内容比较简单,代码功能单一,仅限于导出个Excel内容文件,如果复杂功能,可能需要进一步研究,谢谢!
相关文章:

原生js用Export2Excel导出excel单级表头和多级表头数据方式实现
原生js用Export2Excel导出excel单级表头和多级表头数据方式实现 原生js用Export2Excel导出excel单级表头和多级表头数据方式实现HTML文件导入需要的文件HTML文件中实现导出函数HTML总代码实现汇总(直接复制代码,注意js引入路径) 原生js用Expo…...

急需翻译PDF文件怎么办?pdf翻译在线快速帮你解决
面对满屏幕密密麻麻的pdf文件,我常常感到头疼! 语言障碍让我在获取信息的道路上踌躇不前,但自从我发现了pdf在线翻译成中文的神奇工具,一切问题似乎都迎刃而解。 这些软件不仅让我能够快速跨过语言壁垒,还让我在学术…...
线程安全的集合类和并发数据结构
在Java中,线程安全的集合类和并发数据结构对于处理多线程环境下的数据共享和同步至关重要。这些集合和数据结构通过不同的机制来确保在多线程环境下数据的一致性和完整性。以下是一些常见的线程安全的集合类和并发数据结构: 线程安全的集合类 Vector 描…...
Linux环境下运行介绍
1. 文件编程函数介绍 如果在Linux系统下学习C语言,就会了解到两套文件编程接口函数: C语言标准的文件编程函数: fopen、fread、fwrite、fclose Linux下提供的文件编程函数: open、read、write、close 传参的区别: 基于文件指针: fopen fclose fread…...

Adobe Media Encoder ME 2023-23.6.6.2 解锁版下载安装教程 (专业的视频和音频编码渲染工具)
前言 Adobe Media Encoder(简称Me)是一款专业的音视频格式转码软件,文件格式转换软件。主要用来对音频和视频文件进行编码转换,支持格式非常多,使用系统预设设置,能更好的导出与相关设备兼容的文件。 一、…...
在go语言里io.EOF怎么理解呢?
Go语言在处理文件和其他I/O流时,会使用io.EOF常量来表示文件结束(End Of File)的情况。 io.EOF是Go标准库中io包定义的一个错误值,用于在读取操作达到文件末尾时返回。它是处理文件读取和I/O操作时常见的错误类型之一。当读取操作…...
日常编码工作与提升式学习两不误
在快速迭代的编程世界中,程序员们不仅需要高效完成日常编码任务,还需不断学习新技术、深化专业知识,以应对日益复杂的项目挑战。然而,如何在繁忙琐碎的编码工作与个人成长之间找到平衡,是不少程序员都面临的一个难题。…...

推荐被Stars5.8k的Java框架RuoYi
一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,…...

聊聊适配器模式
目录 适配器模式概念 主要实现方式 主要组成 UML用例图 代码示例 生活场景 应用场景 适配器模式概念 适配器模式属于结构型设计模式,它的主要目的是将一个类的接口转换成客户端所期望的另一种接口形式,使得原本接口不兼容的类可以一起工作。 主…...

韩国服务器的性能如何提升
韩国服务器的性能可以通过硬件升级、网络优化、缓存优化和软件优化来提升。具体方法如下,rak小编为您整理发布韩国服务器的性能如何提升。 1. 硬件升级 CPU升级:选择高性能的多核处理器,可以显著提升计算速度和响应能力。 内存升级࿱…...

体育器材管理系统的设计与实现---附源码 76709
摘 要 本文介绍了一种基于Spring Boot框架的体育器材管理系统,该系统旨在优化学校或教育机构对体育器材的管理流程。通过集成Spring Boot、MySQL、MyBatis以及前端HTML、CSS、JavaScript等技术,实现了器材信息的录入、查询、修改,器材的借用…...

ArcEngine提取面要素公共边的实现方法
1、前言 很久没写ArcEngine的内容了,正好这次有同志提了一个问题:如何用ArcEngine实现批量提取面要素之间的公共边?捣鼓了半天总算是解决了,下面就来说一说解决思路。 2、ArcMap的实现方法 首先准备一份测试数据,如…...

高可用集群keepalived 原理+实战
keepalived 1.高可用集群1.1简介1.2原理1.3 集群类型1.4实现高可用1.5VRRP:Virtual Router Redundancy Protocol1.5.1 VRRP 相关术语1.5.2VRRP 相关技术 2.实验2.1keepalived环境部署2.2抢占模式和非抢占模式2.2.1非抢占模式2.2.2抢占延迟模式 preempt_delay 2.3VIP…...

保姆级教程,带你复现病理AI的经典模型CLAM(一)|项目复现·24-08-19
小罗碎碎念 推文概述 复现CLAM的第一期推文 通过这期推文你首先会学会如何在服务器端使用jupyter编程,比你用其他的编译器(例如PyCharm、VS)会更加的清晰,对新手也更友好。 接着我会介绍如何进行数据预处理,以及你应…...

数据可视化之旅,从数据洞察到图表呈现,可视化的产品设计
图表作为数据可视化的重要工具,是对原始数据进行深度加工与解读的有效手段,它助力我们洞悉数据背后的真相,使我们能更好地适应这个由数据驱动的世界。无论是工作汇报、项目实施、产品设计、后台界面还是数据大屏展示,图表都扮演着…...
ArrayList 和 LinkedList 的区别是什么
数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指…...

在Matlab中进行射频电路S、Z、Y、ABCD等参数的转换
在Matlab中进行射频电路S、Z、Y、ABCD等参数的转换 目录 在Matlab中进行射频电路S、Z、Y、ABCD等参数的转换1、转换案例-3dB电桥2、将转换结果应用到ADS中制造理想3dB电桥器件 在微带线的ABCD矩阵的推导、转换与级联-Matlab计算实例(S、Z、Y参数转换)中&…...

渗透实战——为喜欢的游戏“排忧解难”
本文仅用于技术研究学习,请遵守相关法律,禁止使用本文所提及的相关技术开展非法攻击行为,由于传播、利用本文所提供的信息而造成任何不良后果及损失,与本账号及作者无关。 资料查询来源- 安全社区与AI模型结合探索【文末申请免费…...

政务大数据解决方案(十)
政务大数据解决方案通过建立全面的集成数据平台,整合来自各政府部门的异构数据,运用大数据分析、人工智能和机器学习技术对数据进行深度挖掘与智能化处理,提供实时精准的决策支持,从而提升政策制定和实施的科学性与效率。该方案包…...
使用WebStorm进行高效的全栈JavaScript开发
使用WebStorm进行高效的全栈JavaScript开发,是一个涉及多方面技能与工具利用的过程。WebStorm,作为JetBrains公司推出的一款专为前端开发者和全栈工程师设计的集成开发环境(IDE),以其强大的功能、卓越的性能和友好的用…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...