最近接二开的项目当中,客户要求页面上有下载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不胜感激 !