js-xlsx 导出Excel表格,样式设置
刚刚找到了一个前端导出列表比较不错的插件js-xlsx ,能够继续单元格合并,速度也有了很大提升之后,领导又说,能设置样式吗?例如标题字体、居中等等。我查找了相关的资料,js-xlsx这个插件是支持样式设置的,我安装网上的方法一一尝试了下,都没有作用。最后,通过请教了一位大神,得到了想要的结果。
1、js-xlsx 插件设置样式可能需要一起其他三方放文件。他就是xlsx-style。引用其中的xlsx.core.min.js文件。除此之外,还另外加了一些其他的代码。如下:
(function (win, doc, undefined) {
var xlsxUtils = (function () { var t = { Binary: { fixdata: function (e) { for (var r = "", t = 0, n = 10240; t < e.byteLength / n; ++t)r += String.fromCharCode.apply(null, new Uint8Array(e.slice(t * n, t * n + n))); return r += String.fromCharCode.apply(null, new Uint8Array(e.slice(t * n))) }, s2ab: function (e) { for (var r = new ArrayBuffer(e.length), t = new Uint8Array(r), n = 0; n != e.length; ++n)t[n] = 255 & e.charCodeAt(n); return r } }, _wb: null, _rABS: !1, import: function (e, r) { this.wb = null; var n = new FileReader; n.onload = function (e) { var n = e.target.result; t._wb = t._rABS ? XLSX.read(btoa(t.Binary.fixdata(n)), { type: "base64" }) : XLSX.read(n, { type: "binary" }), "function" == typeof r && r(t._wb) }, t._rABS ? n.readAsArrayBuffer(e) : n.readAsBinaryString(e) }, getSheetByName: function (e) { return XLSX.utils.sheet_to_json(t._wb.Sheets[e]) }, getSheetByIndex: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 0; return t.getSheetByName(t._wb.SheetNames[e]) }, export: function (e, r) { var n = null; for (var o in e) { var a = t.format2Sheet(e[o]); n = t.format2WB(a, o, n) } return t.format2Blob(n, r) }, readDataHead: function (e) { var r = {}, t = Array.isArray(e) ? Object.keys(e[0]) : e, n = !0, o = !1, a = void 0; try { for (var i, f = t[Symbol.iterator](); !(n = (i = f.next()).done); n = !0) { var u = i.value; r[u] = u } } catch (e) { o = !0, a = e } finally { try { !n && f.return && f.return() } finally { if (o) throw a } } return r }, format2Sheet: function (e, r, n, o) { o = o || Object.keys(e[0]), r = r || 0, n = n || 0; var a = {}; return e.map(function (e, a) { return o.map(function (o, i) { return Object.assign({}, { v: e[o], position: (i + r > 25 ? t.getCharCol(i + r) : String.fromCharCode(65 + (i + r))) + (a + 1 + n) }) }) }).reduce(function (e, r) { return e.concat(r) }).forEach(function (e, r) { return a[e.position] = { v: e.v } }), a }, format2WB: function (e, r, t, n) { r = r || "mySheet"; var o = Object.keys(e); return t || (t = { Sheets: {}, SheetNames: [] }), t.SheetNames.push(r), t.Sheets[r] = Object.assign({}, e, { "!ref": n || o[0] + ":" + o[o.length - 1] }), t }, format2Blob: function (e, r) { return new Blob([t.Binary.s2ab(XLSX.write(e, { bookType: void 0 == r ? "xlsx" : r, bookSST: !1, type: "binary" }))], { type: "" }) }, getCharCol: function (e) { for (var r = "", t = 0; e > 0;)t = e % 26 + 1, r = String.fromCharCode(t + 64) + r, e = (e - t) / 26; return r } }; return t })();
win.xlsxUtils = xlsxUtils;
}(window, document))
可以看出这段代码是经过压缩过的,无法解读。。。。将其复制到一个js文件中,引入该js文件即可。
2、对下载函数的封装。s2ab()、saveAs()还和以前的一样,不需要修改,需要修改的是downloadExl()方法。 可访问 https://www.cnblogs.com/toyNotes/p/8617483.html 阅读
/**
* 导出列表方法
* @param {*} data 需要导出的数据 数组形式 [[表头],[数据1],[数据2]...]
* @param {*} fileName 下载的文件名称
* @param {*} titleName 表格标题
* @param {*} time 表格时间范围
* @param {*} keyMap 排序标准
* @param {*} district 地区名称
* @param {*} condition 筛选条件
* @param {*} specialObj 特殊要求,全站搜索使用
*/
var downloadExl = function(data, fileName,titleName,time = '无',keyMap,district,condition,specialObj = []) {
const self = this;
data.unshift({});//空出标题等行
data.unshift({});
data.unshift({});
data.unshift({});
data = xlsxUtils.format2Sheet(data, 0, 0, keyMap);//偏移3行按keyMap顺序转换
var wb = xlsxUtils.format2WB(data, undefined, undefined);
const range = keyMap.length - 1;
const wopts = { bookType: 'xlsx', bookSST: false, type: 'binary' };
var dataInfo = wb.Sheets[wb.SheetNames[0]];
dataInfo["A1"].v = district + '广播电视安全播出监管中心'; //设置表格标题
dataInfo["A2"] = {v: titleName}; //设置表格标题
dataInfo["A3"] = {v: '日期:' + time}; //设置表格日期
dataInfo["A4"] = {v: condition}; //设置筛选条件
dataInfo["!merges"] = [{//合并第一行数据[B1,C1,D1,E1]
s: {//s为开始
c: 0,//开始列
r: 0,//开始取值范围
},
e: {//e结束
c: range,//结束列
r: 0//结束范围
}
},{//合并第一行数据[B2,C2,D2,E2]
s: {//s为开始
c: 0,//开始列
r: 1,//开始取值范围
},
e: {//e结束
c: range,//结束列
r: 1//结束范围
}
},{//合并第一行数据[B3,C3,D3,E3]
s: {//s为开始
c: 0,//开始列
r: 2,//开始取值范围
},
e: {//e结束
c: range,//结束列
r: 2//结束范围
}
},{//合并第一行数据[B3,C3,D3,E3]
s: {//s为开始
c: 0,//开始列
r: 3,//开始取值范围
},
e: {//e结束
c: range,//结束列
r: 3//结束范围
}
}
];
if(specialObj){
let rowNum = 5;
_.each(specialObj,(data,index)=>{
if(data.num){
dataInfo['A' + rowNum].v = data.name + '列表';
dataInfo['A' + rowNum].s = { //设置副标题样式
font: {
name: '宋体',
sz: 14,
color: {rgb: "#FFFF0000"},
bold: false,
italic: false,
underline: false
},
alignment: {
horizontal: "center" ,
vertical: "center"
}
};
dataInfo["!merges"].push(
{
s: {//s为开始
c: 0,//开始列
r: rowNum - 1,//开始取值范围
},
e: {//e结束
c: range,//结束列
r: rowNum - 1//结束范围
}
}
)
_.each(dataInfo,(data,key)=>{
if(key.replace(/[^0-9]/ig,"") == (rowNum +1)){
dataInfo[key].s = {
font: {
name: '宋体',
sz: 11,
color: {rgb: "#FFFF0000"},
bold: true,
italic: false,
underline: false
},
alignment: {
horizontal: "center" ,
vertical: "center"
}
};
}
})
rowNum += data.num + 1;
}
})
}
dataInfo["A1"].s = { //设置主标题样式
font: {
name: '宋体',
sz: 18,
color: {rgb: "#FFFF0000"},
bold: true,
italic: false,
underline: false
},
alignment: {
horizontal: "center" ,
vertical: "center"
}
};
dataInfo["A2"].s = { //设置副标题样式
font: {
name: '宋体',
sz: 16,
color: {rgb: "#FFFF0000"},
bold: false,
italic: false,
underline: false
},
alignment: {
horizontal: "center" ,
vertical: "center"
}
};
dataInfo["A3"].s = { //设置日期样式
font: {
name: '宋体',
sz: 11,
color: {rgb: "#FFFF0000"},
bold: false,
italic: false,
underline: false
}
};
dataInfo["A4"].s = {
font: {
name: '宋体',
sz: 11,
color: {rgb: "#FFFF0000"},
bold: false,
italic: false,
underline: false
}
};
if(specialObj.length == 0){
_.each(dataInfo,(data,key)=>{ //设置表头样式 由于表头是第四行,所以判断其表格单元格编号是否是 4
if(key.replace(/[^0-9]/ig,"") == 5){
dataInfo[key].s = {
font: {
name: '宋体',
sz: 11,
color: {rgb: "#FFFF0000"},
bold: true,
italic: false,
underline: false
},
alignment: {
horizontal: "center" ,
vertical: "center"
}
};
}else if(key.replace(/[^0-9]/ig,"") != 1 && key.replace(/[^0-9]/ig,"") != 2 && key.replace(/[^0-9]/ig,"") != 3){
dataInfo[key].s = {
font: {
name: '宋体',
// sz: 11,
color: {rgb: "#FFFF0000"},
// bold: false,
// italic: false,
// underline: false
}
// alignment: {
// horizontal: "center" ,
// vertical: "center"
// }
};
}
})
}
self.saveAs(xlsxUtils.format2Blob(wb), fileName +".xlsx");
};
这个是我封装的方法,里面有一些适应不同的导出列表的格式要求。个人觉得还有很大的改进空间,对这个插件的理解有限,欢迎各路大神指点。