前端有时就会遇见明明是后端的活,却一定要前端来完成。就比如下面的
需求:前端解析excel文件中的内容,加工成json传给后端,后端加工完json再传给前端,然后前端以excel的形式下载到本地。
下面就分两部分来封装方法
一、解析excel文件
import * as XLSX from 'xlsx'
const getExcelFile=()=>{
let list=[]
let titleList=[]
let files = e.target.files
let fileReader = new FileReader()
fileReader.onload = function (ev) {
try {
let data = ev.target.result
let workbook = XLSX.read(data, {
type: 'binary',
})
let persons = []
} catch (e) {
alert('文件类型不正确')
console.log('文件类型不正确')
return
}
// 表格的表格范围,可用于判断表头是否数量是否正确
let fromTo = ''
for (let sheet in workbook.Sheets) {
if (workbook.Sheets.hasOwnProperty(sheet)) {
fromTo = workbook.Sheets[sheet]['!ref']
list =persons.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]))
//break
}
}
}
titleList = Object.keys(list[0] || {})
//然后我们在以二进制的方式打开文件
fileReader.readAsBinaryString(files[0])
}
下载excel文件到本地
/**
* 注: ! outlist中数据中对象的顺序要和 titleList数组中的字段顺序一样,不然会导致导出的数据混乱
* @param {*} titleList type Array excel的表头列表 titleList=['one,‘two']
* @param {*} outlist type Array excel内容 outlist=[{},{},{}]
* @param {*} name 导出文件的名字 string
*/
const downloadExcel=(titleList, outlist, name)=>{
let str = ''
titleList.forEach(element => {
str += `<td>${element}</td>`
})
str = `<tr>${str}</tr>`
for (let i = 0
str += '<tr>'
for (const item in outlist[i]) {
let cellvalue = outlist[i][item]
//方法1 tr里面加 style="mso-number-format:'\@';" 方法2 是改为 = 'XXXX'格式
//如果纯数字且超过15位 /*let reg = /^[0-9]+.?[0-9]*$/
if ((cellvalue.length>15) && (reg.test(cellvalue))){
// cellvalue = '="' + cellvalue + '"'
//此处用 `取代',具体用法搜索模板字符串 ES6特性
str += `<td style="mso-number-format:'\@';">${cellvalue}</td>`
// str+=`<td>${cellvalue}</td>`
str += '</tr>'
}
const worksheet = '导出结果'
const uri = 'data:application/vnd.ms-excel;base64,'
}
}
// 下载的表格模板数据
const template = `<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<!--[if gte mso 9]>
<xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
<x:ExcelWorksheet>
<x:Name>${worksheet}</x:Name>
<x:WorksheetOptions>
<x:DisplayGridlines/>
</x:WorksheetOptions>
</x:ExcelWorksheet>
</x:ExcelWorksheets>
</x:ExcelWorkbook>
</xml>
<![endif]-->
</head>
<body>
<table>${str}</table>
</body>
</html>`
// 下载模板
function base64(s) {
return window.btoa(unescape(encodeURIComponent(s)))
}
// 自定义文件名
const dlink = document.createElement('a')
dlink.href = uri + base64(template)
dlink.download = `${name}.xls`
document.body.appendChild(dlink)
dlink.click()
// 默认使用“下载”为文件名
// window.location.href = uri + base64(template)
}