Vue表格导出Excel数据,自定义表头,使用xlsx-style修饰

news2024/11/15 15:56:43

继续上篇文章封装导出方法:

效果图:

 1、安装xlsx-style依赖:

yarn add xlsx-style

2、安装node-polyfill-webpack-plugin依赖:

yarn add node-polyfill-webpack-plugin -D

解决报错:jszip is not a constructor

3、配置vue.config.js: !!!配置完重新运行程序

 解决报错:Module not found: Error: Can't resolve 'fs' in \***\xlsx-style

               和 Can‘t resolve ‘./cptable‘ in ‘xxx\node_modules_xlsx

const NodePolyfillPlugin = require("node-polyfill-webpack-plugin")
configureWebpack: {
	plugins: [
		new NodePolyfillPlugin()
	],
	resolve: {
		fallback: {
			fs: false
		}
	},
	externals: {
		'./cptable': 'var cptable',
	},
},

4、在根目录src文件夹下新建excel文件导入Blob.js文件:

/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
(function(view){view.URL=view.URL||view.webkitURL;if(view.Blob&&view.URL){try{new Blob;return}catch(e){}}var BlobBuilder=view.BlobBuilder||view.WebKitBlobBuilder||view.MozBlobBuilder||(function(view){var get_class=function(object){return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]},FakeBlobBuilder=function BlobBuilder(){this.data=[]},FakeBlob=function Blob(data,type,encoding){this.data=data;this.size=data.length;this.type=type;this.encoding=encoding},FBB_proto=FakeBlobBuilder.prototype,FB_proto=FakeBlob.prototype,FileReaderSync=view.FileReaderSync,FileException=function(type){this.code=this[this.name=type]},file_ex_codes=("NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "+"NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR").split(" "),file_ex_code=file_ex_codes.length,real_URL=view.URL||view.webkitURL||view,real_create_object_URL=real_URL.createObjectURL,real_revoke_object_URL=real_URL.revokeObjectURL,URL=real_URL,btoa=view.btoa,atob=view.atob,ArrayBuffer=view.ArrayBuffer,Uint8Array=view.Uint8Array;FakeBlob.fake=FB_proto.fake=true;while(file_ex_code--){FileException.prototype[file_ex_codes[file_ex_code]]=file_ex_code+1}if(!real_URL.createObjectURL){URL=view.URL={}}URL.createObjectURL=function(blob){var type=blob.type,data_URI_header;if(type===null){type="application/octet-stream"}if(blob instanceof FakeBlob){data_URI_header="data:"+type;if(blob.encoding==="base64"){return data_URI_header+";base64,"+blob.data}else{if(blob.encoding==="URI"){return data_URI_header+","+decodeURIComponent(blob.data)}}if(btoa){return data_URI_header+";base64,"+btoa(blob.data)}else{return data_URI_header+","+encodeURIComponent(blob.data)}}else{if(real_create_object_URL){return real_create_object_URL.call(real_URL,blob)}}};URL.revokeObjectURL=function(object_URL){if(object_URL.substring(0,5)!=="data:"&&real_revoke_object_URL){real_revoke_object_URL.call(real_URL,object_URL)}};FBB_proto.append=function(data){var bb=this.data;if(Uint8Array&&(data instanceof ArrayBuffer||data instanceof Uint8Array)){var str="",buf=new Uint8Array(data),i=0,buf_len=buf.length;for(;i<buf_len;i++){str+=String.fromCharCode(buf[i])}bb.push(str)}else{if(get_class(data)==="Blob"||get_class(data)==="File"){if(FileReaderSync){var fr=new FileReaderSync;bb.push(fr.readAsBinaryString(data))}else{throw new FileException("NOT_READABLE_ERR")}}else{if(data instanceof FakeBlob){if(data.encoding==="base64"&&atob){bb.push(atob(data.data))}else{if(data.encoding==="URI"){bb.push(decodeURIComponent(data.data))}else{if(data.encoding==="raw"){bb.push(data.data)}}}}else{if(typeof data!=="string"){data+=""}bb.push(unescape(encodeURIComponent(data)))}}}};FBB_proto.getBlob=function(type){if(!arguments.length){type=null}return new FakeBlob(this.data.join(""),type,"raw")};FBB_proto.toString=function(){return"[object BlobBuilder]"};FB_proto.slice=function(start,end,type){var args=arguments.length;if(args<3){type=null}return new FakeBlob(this.data.slice(start,args>1?end:this.data.length),type,this.encoding)};FB_proto.toString=function(){return"[object Blob]"};FB_proto.close=function(){this.size=this.data.length=0};return FakeBlobBuilder}(view));view.Blob=function Blob(blobParts,options){var type=options?(options.type||""):"";var builder=new BlobBuilder();if(blobParts){for(var i=0,len=blobParts.length;i<len;i++){builder.append(blobParts[i])}}return builder.getBlob(type)}}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content||this));

 5、在文件夹/utils/TableToExcel.js引入(全部代码,复制使用即可):

import * as XLSX from "xlsx";
import XLSXS from "xlsx-style";
import FileSaver from "file-saver";
import '@/excel/Blob.js';

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

function sheet_from_array_of_arrays(data) {
	let ws = {};
	let range = {
		s: {
			c: 10000000,
			r: 10000000
		},
		e: {
			c: 0,
			r: 0
		}
	};
	for (let R = 0; R !== data.length; ++R) {
		for (let 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;
			let cell = {
				v: data[R][C]
			};
			if (cell.v == null) continue;
			let 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) {
	let buf = new ArrayBuffer(s.length);
	let view = new Uint8Array(buf);
	for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
	return buf;
}

function autoWidth(data) {
	/*设置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 + 4
			};
		} else {
			return {
				'wch': val.toString().length + 4
			};
		}
	}))
	/*以第一行为初始值*/
	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'];
			}
		}
	}
	return result;
}

const uppercaseAlphabet = [];
for (let i = 65; i <= 90; i++) {
	const letter = String.fromCharCode(i);
	uppercaseAlphabet.push(letter);
}


function isKey(key) {//判断是不是表头
	let Y = false
	for (let i = 65; i <= 90; i++) {
		const letter = String.fromCharCode(i);
		if (key === `${letter}1`) {
			Y = true
		}
	}
	return Y
}

function export_json_to_excel(tHeader, jsonData, defaultTitle) {
	/* original data */
	let data = jsonData;
	data.unshift(tHeader);
	let ws_name = "SheetJS";

	let wb = new Workbook();
	let ws = sheet_from_array_of_arrays(data);
	ws['!cols'] = autoWidth(data); //设置单元格宽度自适应
	Object.keys(ws).forEach((key) => { //这里遍历单元格给单元格对象设置属性,s为控制样式的属性
		if (key.indexOf('!') < 0) {
			// console.log(key);

			if (isKey(key)) {
				// 设置表头文字加粗字号突出
				ws[key].s = {
					alignment: { //对齐方式
						horizontal: 'center', //水平居中
						vertical: 'center', //竖直居中
					},
					font: {
						sz: 13, // 字号
						name: '楷体', // 字体
						bold: true, //加粗
					},
					fill: {
						fgColor: { //单元格背景颜色
							rgb: "FFFFAA00"
						},
					}
				}
			} else {
				//为所有的单元格设置样式
				ws[key].s = {
					alignment: { //对齐方式
						horizontal: 'center', //水平居中
						vertical: 'center', //竖直居中
						wrapText: true, //自动换行
					},
					font: {
						sz: 12, // 字号
						name: '楷体' // 字体
					},
				}
			}

		}
	})

	wb.SheetNames.push(ws_name);
	wb.Sheets[ws_name] = ws;

	let wbout = XLSXS.write(wb, {
		bookType: 'xlsx',
		bookSST: false,
		type: 'binary'
	});
	let title = defaultTitle || '表单';
	saveAs(new Blob([s2ab(wbout)], {
		type: "application/octet-stream"
	}), title + ".xlsx")
}

export default {
	// 导出Excel表格
	// name表示生成excel的文件名     IDName表示表格的id
	exportExcel(name, IDName) {
		var fix_l = document.querySelector('.el-table__fixed'); //fixed 或者 fixed='left'
		var fix_r = document.querySelector('.el-table__fixed-right'); //fixed='right'
		var wb;
		// 以下代码解决table中使用fixed属性导致导出的数据重复问题
		if (fix_l) { //判断是否有浮动或者是左浮动
			wb = XLSX.utils.table_to_book(document.querySelector(IDName).removeChild(fix_l));
			document.querySelector(IDName).appendChild(fix_l);
		} else if (fix_r) { //判断是否有右浮动
			wb = XLSX.utils.table_to_book(document.querySelector(IDName).removeChild(fix_r));
			document.querySelector(IDName).appendChild(fix_r);
		} else if (fix_l && fix_r) { //左右浮动都存在
			wb = XLSX.utils.table_to_book(document.querySelector(IDName).removeChild(fix_l).removeChild(fix_r));
			document.querySelector(IDName).appendChild(fix_l).appendChild(fix_r);
		} else { //没有浮动
			wb = XLSX.utils.table_to_book(document.querySelector(IDName))
		}
		// var wb = XLSX.utils.table_to_book(document.querySelector(IDName))
		var wbout = XLSX.write(wb, {
			bookType: 'xlsx',
			bookSST: true,
			type: 'array'
		})
		try {
			FileSaver.saveAs(new Blob([wbout], {
				type: 'application/octet-stream'
			}), `${name}.xlsx`);
		} catch (e) {
			if (typeof console !== 'undefined') console.log(e, wbout)
		}
		return wbout;
	},

	// 导出Excel表格自定义标头和内容
	// excelData表示el-table数据       tableName表示生成excel的文件名
	export2Excel(excelData, excelObj, tableName) {
		require.ensure([], () => {
			// 导出的excel的表头字段可自定义
			let tHeader = []
			// 对象属性,对应于tHeader,即prop的值,可自定义导出字段
			let filterVal = []
			for (let i in excelObj) {
				tHeader.push(i)
				filterVal.push(excelObj[i])
			}
			// 格式转换数据
			const data = excelData.map(v => filterVal.map(j => v[j]))
			// console.log(data);
			export_json_to_excel(tHeader, data, tableName) // 导出的表格名称,可自定义
		})
	},
}

 6、全局引入注册main.js:

import TableToExcel from '@/utils/TableToExcel';
Vue.prototype.$TableToExcels = TableToExcel

7、页面使用:

exportBtn() {
	//导出
	// this.$TableToExcels.exportExcel('导出的Excel名', '#table的id名')

	let excelData = this.tableData//导出的所有数据集合
	let excelObj = { //自定义表头 自定义对应的字段值 即prop的值
		'所属疗区':'OrgName',
		'坐落名称':'StandName',
		'土地总面积(m²)':'StandArea',
		'坐标所在地':'StandEncode'
	}
	this.$TableToExcels.export2Excel(excelData,excelObj,'导出的Excel名')
},

另外使用xlsx-style还可以设置单元格的其他的格式,可以参考这篇文章,很全。
JavaScript导出excel文件,并修改文件样式

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

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

相关文章

Cilium系列-13-启用XDP加速及Cilium性能调优总结

系列文章 Cilium 系列文章 前言 将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能. 但是通过对 Cilium 不同模式的切换/功能的启用, 可以进一步提升 Cilium 的网络性能. 具体调优项包括不限于: 启用本地路由(Native Routing)完全替换 KubeProx…

广西茶叶元宇宙 武隆以茶为媒 推动茶文旅产业融合发展

8月4日&#xff0c;重庆市武隆区启动为期3天的“武隆首届玩茶荟”。本次活动以“中国最美玩茶地——武隆”为主题&#xff0c;吸引众多国内知名专家、茶企和茶馆相关负责人&#xff0c;共同探索武隆茶文旅融合发展新路径和新业态。 广西茶叶元宇宙&#xff1a;广西茶叶元宇宙 …

GD32F103的EXTI中断和EXTI事件

GD32F103的EXTI可以产生中断&#xff0c;也产生事件信号。 GD32F03的EXTI触发源: 1、I/O管脚的16根线&#xff1b; 2、内部模块的4根线(包括LVD、RTC闹钟、USB唤醒、以太网唤醒)。 通过配置GPIO模块的AFIO_EXTISSx寄存器&#xff0c;所有的GPIO管脚都可以被选作EXTI的触发源…

近阶段的一些思考

文章目录 近阶段&#xff08;大约一个多月&#xff09;一直在投入某个开发项目中&#xff0c;没有机会静下来思考一番。对于自己而言&#xff0c;忙碌是一种不好的现象&#xff0c;不应该认为是一件理所当然的事情&#xff0c;应该是一种危机的存在&#xff0c;这种状态持续两周…

关注提示工程—本世纪最重要的技能可能就是与AI人工智能对话

本文目录与主要结构 引言&#xff1a;介绍提示工程的概念和背景&#xff0c;说明为什么它是本世纪最重要的技能之一。 正文&#xff1a; 一、提示工程的基本原理和方法&#xff1a;介绍什么是提示、如何设计和优化提示、如何使用提示与语言模型进行交互。 二、提示工程的应…

Nginx启动报错- Failed to start The nginx HTTP and reverse proxy server

根据日志&#xff0c;仍然出现 “bind() to 0.0.0.0:8888 failed (13: Permission denied)” 错误。这意味着 Nginx 仍然无法绑定到 8888 端口&#xff0c;即使使用 root 权限。 请执行以下操作来进一步排查问题&#xff1a; 确保没有其他进程占用 8888 端口&#xff1a;使用以…

【动态规划】回文子串专题

文章目录 1. 【LeetCode】647. 回文子串1.1 思路讲解1.1.1 方法选择1.1.2 dp表的创建1.1.3 状态转移方程1.1.4 填表顺序 1.2 整体代码 2. 【LeetCode】5. 最长回文串2.1 思路讲解2.2 代码实现 3.【LeetCode】094. 分割回文串II3.1 解题思路3.1.1 创建dp表3.1.2 状态转移方程3.1…

[每日习题]第一个只出现一次的字符 小易的升级之路——牛客习题

hello,大家好&#xff0c;这里是bang___bang_&#xff0c;本篇记录2道牛客习题&#xff0c;第一个只出现一次的字符&#xff08;简单&#xff09;&#xff0c;小易的升级之路&#xff08;简单&#xff09;&#xff0c;如有需要&#xff0c;希望能有所帮助&#xff01; 目录 1️…

继承(Inheritance)

Odoo的一个强大方面是它的模块化。模块专用于业务需求&#xff0c;但模块也可以相互交互。这对于扩展现有模块的功能非常有用。例如&#xff0c;在我们的房地产场景中&#xff0c;我们希望在常规用户视图中直接显示销售人员的财产列表。 在介绍特定的Odoo模块继承之前&#xf…

vue diff 双端比较算法

文章目录 双端指针比较策略命中策略四命中策略二命中策略三命中策略一未命中四种策略&#xff0c;遍历旧节点列表新增情况一新增情况二 删除节点双端比较的优势 双端指针 使用四个变量 oldStartIdx、oldEndIdx、newStartIdx 以及 newEndIdx 分别存储旧 children 和新 children …

26 MFC序列化函数

文章目录 Serialize对于存储文件的序列化 Serialize Serialize 是一个在 MFC (Microsoft Foundation Classes) 中常用的函数或概念。它用于将对象的数据进行序列化和反序列化&#xff0c;便于在不同的场景中保存、传输和恢复对象的状态。 在 MFC 中&#xff0c;Serialize 函数…

如何查询显卡算力

感谢阅读 找到demo_suite此目录下打开控制台 找到demo_suite 一般在 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\extras\demo_suite 这个目录 注意&#xff1a; 1.V后面的数字表示版本&#xff0c;请根据自己的版本进行更改 2.此目录为我的安装目录&#xff0…

python批量检查folder中的文件是否符合要求

目录 问题描述&#xff1a; 问题解决&#xff1a; 问题描述&#xff1a; 最近在手动整理一些文档&#xff0c;要求是每一个folder以ID命名&#xff0c;每一个folder中存放三个内容&#xff08;如下图&#xff09;。如何实现批量检查每一个folder三个内容是否存在&#xff1f;…

【2023年电赛国一必备】E题报告模板--可直接使用

创作不易&#xff0c;麻烦关注CSDN【技术交流、免费报告资料】 通过百度网盘分享的文件&#xff1a;https://pan.baidu.com/s/1aXzYwLMLx_b59abvplUiYw?pwddn71 提取码:dn71 复制这段内容打开「百度网盘APP 即可获取」 任务 图1 任务内容 要求 图2 基本要求内容 图3 发挥部…

K8s实战入门(三)

文章目录 3. 实战入门3.1 Namespace3.1.1 测试两个不同的名称空间之间的 Pod 是否连通性 3.2 Pod3.3 Label3.4 Deployment3.5 Service 3. 实战入门 本章节将介绍如何在kubernetes集群中部署一个nginx服务&#xff0c;并且能够对其进行访问。 3.1 Namespace Namespace是kuber…

【电源专题】充电IC与DC-DC有什么区别

充电IC和DC-DC一样使用很广泛,如手机、平板等需要电池供电的系统中,一般都会见到充电IC的身影。那么大家有没有考虑过一个问题。充电IC与DC-DC有什么区别? 首先如下所示为充电IC的两个阶段,一个阶段是恒流充电阶段,我们一般称之为CC阶段,另一个是恒压充电阶段,我们称之为…

Java课题笔记~ IoC 控制反转

二、IoC 控制反转 控制反转&#xff08;IoC&#xff0c;Inversion of Control&#xff09;&#xff0c;是一个概念&#xff0c;是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器&#xff0c;通过容器来实现对象的 装配和管理。控制反转就是对对象控制权的转移&a…

ShaderToy着色器移植到Three.js全过程记录

推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 作为 Publicis Pixelpark Innovationlab 研究的一部分&#xff0c;我们研究了如何将较低底层的语言用于网络技术。 显而易见的选择似乎是 asm.js 或 WebAssembly。 但你也可以使用 WebGL 着色器来解决面向机器的问题。 …

springboot+vue网红酒店客房预定系统的设计与实现_ui9bt

随着计算机技术发展&#xff0c;计算机系统的应用已延伸到社会的各个领域&#xff0c;大量基于网络的广泛应用给生活带来了十分的便利。所以把网红酒店预定管理与现在网络相结合&#xff0c;利用计算机搭建网红酒店预定系统&#xff0c;实现网红酒店预定的信息化。则对于进一步…

【验证测试】未初始化的全局变量和局部变量的初值

验证目标&#xff1a; 未初始化的全局变量的初值为 0未初始化的局部变量的初值为随机值 测试用例&#xff1a; #include <stdio.h>char gval1; int gval2; static long gval3;int main() {unsigned char uchTmp1;unsigned int uTmp2;printf("%d\n", gval1)…