之前写过一个js导出excel的代码,一直用着好好的,最近突然报错了,研究了半天发现在表格列数超过26列的时候就会出现这个问题,也是就excel的列是A-Z,然后跟着是AA,AB,AC...这种,在超出26列时前端导出就会报错了,所以又加了下特殊处理,在超过26列时生成sheet中修改了列头,给大家分享一下
this.handleExport = function () {
// 此处_this.onShowItemList为要导出的数据列表
var downloadItemList = angular.copy(_this.onShowItemList);
downloadItemList.forEach(function (item) {
Object.keys(item).forEach(function (key) {
var val = 0;
// 这里对英文逗号做了下处理,转换成了中文逗号,否则后续使用时会有问题
if (!isNaN(Number(item[key])) || item[key].indexOf(',') > -1) {
val = item[key].replace(/,/g, '');
item[key] = val;
}
})
})
generateExcel(downloadItemList, _this.menuName + '.xlsx');
}
/**
* @listItems 要导出的数据
* @excelName 导出excel的名称
*/
function generateExcel(listItems, excelName) {
_this.exportAllData = [];
_this.exportAllData.push(['序号']);
// 这里是有多列表头的情况,正常直接使用else中的部分就可以了
if (_this.titleList3 && _this.titleList3.length > 0 && _this.titleList2 && _this.titleList2.length > 0) {
_this.exportAllData.push([1]);
_this.exportAllData.push([2]);
_this.titleList3.forEach(function (item) {
_this.exportAllData[0].push(item);
})
_this.titleList2.forEach(function (item) {
_this.exportAllData[1].push(item);
})
angular.forEach(_this.titleList, function (a, b, c) {
_this.exportAllData[2].push(a);
})
} else if (_this.titleList2 && _this.titleList2.length > 0) {
_this.exportAllData.push([1]);
_this.titleList2.forEach(function (item) {
_this.exportAllData[0].push(item);
})
angular.forEach(_this.titleList, function (a, b, c) {
_this.exportAllData[1].push(a);
})
} else {
angular.forEach(_this.titleList, function (a, b, c) {
_this.exportAllData[0].push(a);
})
}
angular.forEach(listItems, function (value, key) {
var num = Object.keys(_this.itemList[_this.itemList.length - 1]).length;
_this.exportAllData[key + num] = [key + num];
angular.forEach(_this.valueList, function (a, b, c) {
_this.exportAllData[key + num].push(value[a]);
})
})
var str = '';
for (var i = 0; i < _this.exportAllData.length; i++) {
for (var item in _this.exportAllData[i]) {
var newStr = '';
if (_this.exportAllData[i][item] && _this.exportAllData[i][item].length > 0) {
newStr = isNaN(_this.exportAllData[i][item]) ? (_this.exportAllData[i][item] || '') : _this.exportAllData[i][item].replace(',', ',')
} else {
newStr = _this.exportAllData[i][item] || '';
}
str += newStr + '\t,';
}
str += '\n';
}
exportExcel(str, excelName);
}
function csv2sheet(csv) {
var sheet = {}; // 将要生成的sheet
csv = csv.split('\n');
csv.forEach(function (row, i) {
row = row.split(',');
var tmpArr = [];
row.forEach(function (item) {
tmpArr.push(item.trim());
});
row = tmpArr;
// 这里就是文章开头提到的当列数超过26列时的处理
var charCode = row.length > 26 ? String.fromCharCode(65 + row.length/26 - 1) + String.fromCharCode(65 + row.length%26 - 1) : String.fromCharCode(65 + row.length - 1);
if (i == 0) sheet['!ref'] = 'A1:' + charCode + (csv.length - 1);
row.forEach(function (col, j) {
var code = j > 26 ? String.fromCharCode(65 + row.length/26 - 1) + String.fromCharCode(65 + j%26) : String.fromCharCode(65 + j);
// 这一部分是判断是否为百分比类型的数据,如果是的话当前单元格按照nnumber类型处理,
// 这样做的好处是方便导出的文件直接进行排序
if (col.indexOf('%') > -1 && !isNaN(col.trim().replace('%', ''))) {
var percentValue = col.trim();
sheet[code + (i + 1)] = {
v: Number(percentValue.substring(0, percentValue.length - 1)) / 100,
t: 'n',
z: '0.00%'
};
} else {
sheet[code + (i + 1)] = {v: Number((col).trim()) || col.trim(), t: 'n'};
}
});
});
return sheet;
}
// 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
function sheet2blob(sheet, sheetName) {
sheetName = sheetName || 'sheet1';
var workbook = {
SheetNames: [sheetName],
Sheets: {}
};
workbook.Sheets[sheetName] = sheet;
// 生成excel的配置项
var wopts = {
bookType: 'xlsx', // 要生成的文件类型
bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
type: 'binary'
};
var wbout = XLSX.write(workbook, wopts);
var blob = new Blob([s2ab(wbout)], {type: "application/octet-stream"});
// 字符串转ArrayBuffer
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) & 0xFF;
return buf;
}
return blob;
}
function openDownloadDialog(url, saveName) {
if (typeof url == 'object' && url instanceof Blob) {
url = URL.createObjectURL(url); // 创建blob地址
}
var aLink = document.createElement('a');
aLink.href = url;
aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
var event;
if (window.MouseEvent) event = new MouseEvent('click');
else {
event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
}
aLink.dispatchEvent(event);
}
function exportExcel(csv, excelName) {
var sheet = csv2sheet(csv);
var blob = sheet2blob(sheet);
openDownloadDialog(blob, excelName);
}