利用xlsx-style实现前端导出excle表并修改样式

December 17, 2023
测试
测试
测试
测试
7 分钟阅读

最近接二开的项目当中,客户要求页面上有下载excle模板的按钮,并提供输入数据的基本模板

本来项目中一些数据量较大的导出确实是后台来做的。但是有些数据较少的,比如这种只是模板的excle表生成,前端也是可以来实现的。 项目本来用的是xlsx实现的导出,但是这个插件只支持基本的数据导出,不支持样式的修改,所以这里又安装了xlsx-style和 file-saver的依赖

    npm install xlsx --save 
    npm install xlsx-style --save
    npm install file-saver --save

在安装完xlsx-style后,应该会有报错Can‘t resolve ‘./cptable‘ in ‘xxx\node_modules_xlsx,稳定解决的方法是,在项目依赖包里修改下xlsx-style的源代码

node_modules\xlsx-style\dist\cpexcel.js

807行替换成 var cpt = cptable 不过要备注好,下次安装依赖时也记得修改。 或者是vue.config.js中添加

configureWebpack: {
externals:{
  './cptable': 'var cptable'
  },
}

在所用页面或者组件引入模块

import * as XLSX from 'xlsx';
import XLSXS from 'xlsx-style';
import FileSaver from 'file-saver';

这里是将导出的方法进行了封装成公共的方法,接受三个参数,json数据、表名、类型。

前面讲json数据传出,公共的方法封装在mixin里,数据进来后,进行处理,转数组,并通过XLSX.utils.json_to_sheet转为sheet对象

业务要求,生成的模板里有两行示例,并且是黄色背景

那么两行示例数据,已经有了,主要是样式的修改。样式修改的对象是sheet对象。我这里因为要单独修改,所以进行了遍历。

for (let i in wb.Sheets[name]) {
				// 如果是导出模板 修改导出的excle第二、三行【A2-F3】的背景颜色 #FFFF00
				if (name == '床位导入模板') {
					wb.Sheets[name]['!cols'] = [];
					
					//设置表头样式
					if (['A1', 'B1', 'C1', 'D1', 'E1'].includes(i)) {
						wb.Sheets[name][i].s = {
							border: {
								top: {
									style: 'thin',
								},
								bottom: {
									style: 'thin',
								},
								left: {
									style: 'thin',
								},
								right: {
									style: 'thin',
								},
							},
							font: {
								sz: 12,
								bold: true,
								color: {
									rgb: 'FFFFFF', //白色
								},
							},
							alignment: {
								horizontal: 'center',
								vertical: 'center',
								wrapText: true,
							},
							fill: {
								fgColor: {
									rgb: '808080', //灰色
								},
							},
						};
					}
					if (['A2', 'A3', 'B2', 'B3', 'C2', 'C3', 'D2', 'D3', 'E2', 'E3', 'F2', 'F3'].includes(i)) {
						wb.Sheets[name][i].s = {
							fill: {
								fgColor: {
									rgb: 'FFFF00',
								},
							},
							border: {
								top: {
									style: 'thin',
								},
								bottom: {
									style: 'thin',
								},
								left: {
									style: 'thin',
								},
								right: {
									style: 'thin',
								},
							},
						};
					}
					// 每列宽度设置100
					wb.Sheets[name]['!cols']= [{ wpx: 200 },{ wpx: 100 },{ wpx: 100 },{ wpx: 100 },{ wpx: 100 },{ wpx: 200 }];
				}
			}

这里是准备不同的单元格进行了背景、边框、对齐方式等修改。

这个地方,我也是卡了好久,总结经验主要是两点:

第一、一开始只安装了xlsx-style的依赖,没有安装file-saver,设置都没有生效

第二、修改样式的对象,这里设置要看清修改的对象数据形式。可以打印出来看下

我这里 console.log('修改的对象',wb.Sheets[name][i]); 出来的是每一个单元格的属性,v代表单元格内容,t代表值的类型(字符串),s是样式,我们上面修改添加样式,也是准对的每一项的s去进行的修改。基本上明确了这个思路,更多样式的修改都是类似的写法。

修改完样式,我们要将数据导出

// 导出Excel, 注意这里用到的是XLSXS对象
			let wbout = XLSXS.write(wb, {
				bookType: 'xlsx',
				bookSST: false,
				type: 'binary',
			});
			FileSaver.saveAs(
				new Blob([this.s2ab(wbout)], {
					type: 'application/octet-stream',
				}),
				filename
			);
		},
s2ab(s) {
			//如果存在ArrayBuffer对象(es6) 最好采用该对象
			if (typeof ArrayBuffer !== 'undefined') {
				//1、创建一个字节长度为s.length的内存区域
				const buf = new ArrayBuffer(s.length);
				//2、创建一个指向buf的Unit8视图,开始于字节0,直到缓冲区的末尾
				const view = new Uint8Array(buf);
				//3、返回指定位置的字符的Unicode编码
				for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
				return buf;
			} else {
				const buf = new Array(s.length);
				for (let i = 0; i !== s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff;
				return buf;
			}
		},

这里我们将数据导出为xlsx对象,利用filesaver进行读写传输,这里代码基本可以复用。

到这里,修改excle表样式的需求就基本实现了,上面修改样式的代码有些冗长还需要整理,因为是公用的方法,我这里是根据导入文件名字去进行单独的表的样式改动,后面也可以把一些公共的样式提取,如果要单独设置某个表样式,可以再加一个形参去进行判定修改。

最后

如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:http://github.crmeb.net/u/defu不胜感激 !

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多