提示: 该方法有性能问题,建议在导出数据小于500行的数据时候进行使用。数据量较多的情况下,依然推荐后端导出!
一. index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>excel导出</title>
</head>
<body>
<button onclick="downLoad()">导出</button>
<script src="./xlsx.core.min.js"></script>
<script src="./02-多表导出.js"></script>
<script src="./index02.js"></script>
</body>
</html>
二、02-多表导出.js
;(function(window) {
/**
* 需要三个参数
* @title: 文件名 字符串
* @sheets: sheet名称 数组 ["瞬时流量(m³/h)", "液位(m)"]
* @dataAll:相应数据 数组
*
* */
// dataAll 的数据形式
// [
// [['时间','m'],['2012','10'],['2012','10']], // sheet1
// [['时间','m'],['2012','10'],['2012','10']], // sheet2
// [['时间','m'],['2012','10'],['2012','10']], // ....
// ]
function exportExcel(title = 'demo', sheets = [], dataAll = []) {
if (sheets.length === 0 || dataAll.length === 0) return
// 数据处理
// 第一步:数据格式处理
let keyObj = {}
let tmpObj = {}
let tmpArr = []
let SheetNames = []
let Units = []
// 第一次处理
sheets.forEach(item => {
let index = item.indexOf('(')
let length = item.length
if (index !== -1) {
SheetNames.push(item.substr(0, index))
Units.push(item.substring(index + 1, length - 1))
} else {
SheetNames.push(item)
Units.push(item)
}
})
// 添加 表头
dataAll.forEach((item, index) => {
item.unshift(['时间', Units[index]])
})
SheetNames.forEach((item, index) => {
keyObj[index] = []
tmpObj[index] = []
dataAll[index].forEach((v, i) => {
v.forEach((it, inx) => {
let key = String.fromCharCode(65 + inx) + (i + 1)
keyObj[index].push(key)
tmpObj[index].push({
position: key,
v: it
})
})
})
})
// 第二次处理
for (let i in tmpObj) {
tmpArr[i] = tmpObj[i].reduce(
(prev, next) =>
Object.assign({}, prev, {
[next.position]: { v: next.v }
}),
{}
)
}
// 第二步: 合成 Sheets
let Sheets = {}
SheetNames.forEach((item, index) => {
let ref = keyObj[index][0] + ':' + keyObj[index][keyObj[index].length - 1]
Sheets[item] = Object.assign({}, tmpArr[index], { '!ref': ref })
})
let wb = {
SheetNames,
Sheets
}
save(wb, `${title}${+new Date()}.xlsx`)
// end
}
function save(wb, fileName) {
let wopts = {
bookType: 'xlsx',
bookSST: false,
type: 'binary'
}
let xw = XLSX.write(wb, wopts)
let obj = new Blob([s2ab(xw)], {
type: ''
})
let elem = document.createElement('a')
elem.download = fileName || '下载'
elem.href = URL.createObjectURL(obj)
elem.click()
setTimeout(function() {
URL.revokeObjectURL(obj)
}, 100)
}
function s2ab(s) {
if (typeof ArrayBuffer !== 'undefined') {
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
} else {
let buf = new Array(s.length)
for (let i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff
return buf
}
}
window.exportExcel = exportExcel
})(window)
三、测试数据 index02.js
/**
* 需要三个参数
* @title: 文件名 字符串
* @sheets: 指标名称 数组 ["瞬时流量(m³/h)", "液位(m)", "COD(mg/L)", "PH", "NH3-N(mg/L)"]
* @dataAll:相应数据 数组
*
* */
// dataAll 的数据形式
// [
// [['时间','m'],['2012','10'],['2012','10']], // sheet1
// [['时间','m'],['2012','10'],['2012','10']], // sheet2
// [['时间','m'],['2012','10'],['2012','10']], // ....
//
let sheets = ['aa', 'bb']
let dataAll = [
[
['时间', '地址'],
['2011', 'a'],
['2012', 'b']
],
[
['时间', '地址'],
['2011', 'c'],
['2012', 'd']
]
]
function downLoad() {
exportExcel('多表导出', sheets, dataAll)
}