前言
大家好,我是沐浴在曙光下的贰货道士 。今年计划出一个使用第三方库的专栏,介绍一些在项目中常用的第三方库。而今天迎来了我们的第一位主角 --- excel
,有喜欢本文的朋友,欢迎一键三连哦~
前端开发与excel
之间不得不说的故事
a. excel
解析数据
需求分析: 在某些场景下,前端需要将上传的excel
文件解析为表格数据,并展示在页面上,这个时候就涉及到excel
的解析(sheetjs官方github)。
首先,我们需要安装依赖:npm install xlsx
。依赖安装完成后,就可以愉快地操作了:
html
<template>
<div class="app-container system-home">
<el-upload
action="#"
:auto-upload="false"
accept=".xlsx,.xls"
:show-file-list="false"
:on-change="onChange"
>
<el-button size="small" type="primary">上传excel文件</el-button>
</el-upload>
</div>
</template>
<script>
import xlsx from 'xlsx'
// import * as xlsx from 'xlsx'(视版本而定)
export default {
data() {
return {
excelData: []
}
},
methods: {
async onChange(file) {
let dataBinary = await new Promise((resolve) => {
`https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader`
let reader = new FileReader()
`将文件读取为二进制字符串`
reader.readAsBinaryString(file.raw)
reader.onload = (ev) => {
`通过监听onload事件,在文件读取完成后,将结果解析为二进制字符串,并将其传递给resolve函数`
resolve(ev.target.result)
}
})
`将二进制字符串解析为工作簿,cellDates: true用于将日期单元格解析为日期对象`
let workBook = xlsx.read(dataBinary, { type: 'binary', cellDates: true })
`获取工作簿中第一个工作表Sheet的引用`
let firstWorkSheet = workBook.Sheets[workBook.SheetNames[0]]
`将工作表转换为JSON格式的数据,返回一个包含工作表数据的数组`
const data = xlsx.utils.sheet_to_json(firstWorkSheet)
`格式化数据,重置数组对象的key值`
this.formatData(data)
},
formatData(data) {
this.excelData = data.map((item) => ({
singer: item['歌手'],
song: item['歌名'],
hot: item['热度(亿)']
}))
console.log('this.excelData', this.excelData)
}
}
}
</script>
假定我们上传的excel
文件长这个样子:
点击页面上的上传excel
文件按钮,并选择需要上传的excel
文件,就会在控制台上显示我们需要获取的最终数据:
至于最后的表格数据展示,就靠广大掘友们自行发挥了~
b. excel
导出
需求分析: 在某些场景下,需要前端将数据导出为excel
文件(FileSaver.js官方github)。
除了需要安装xlsx
依赖外,我们还需要安装依赖:npm install file-saver
。依赖安装完成后,就可以愉快地操作了。
1. 前端导出表格上的数据
html
<template>
<div class="app-container system-home">
<loading-btn
type="primary"
size="mini"
@click="exportHandler(formatData(excelData), 'songs.xlsx')"
>
导出为excel文件
</loading-btn>
</div>
</template>
<script>
import xlsx from 'xlsx'
// import * as xlsx from 'xlsx'(视版本而定)
import { saveAs } from 'file-saver'
export default {
data() {
return {
`假定这些数据是需要我们前端导出的表格数据: `
excelData: [
{
singer: '周杰伦',
song: '搁浅',
hot: '1300.46'
},
{
singer: '周杰伦',
song: '退后',
hot: '999.99'
},
{
singer: '周杰伦',
song: '说了再见',
hot: '1221.67'
},
{
singer: '周杰伦',
song: '最长的电影',
hot: '2004.79'
},
{
singer: '周杰伦',
song: '我落泪情绪零碎',
hot: '2241.63'
},
{
singer: '林俊杰',
song: '圆圆圈圈',
hot: '1200.24'
},
{
singer: '林俊杰',
song: '浪漫广西',
hot: '666.66'
},
{
singer: '华晨宇',
song: '做法',
hot: '0.00 '
},
{
singer: '蔡徐坤',
song: '只因你太美',
hot: '99.86'
}
]
}
},
methods: {
formatData(data) {
return data.map(({ singer, song, hot }) => ({
'歌手': singer,
'歌名': song,
'热度(亿)': hot
}))
},
`可抽取为公共方法,data是导出数据,name是导出的xlsx名称`
exportHandler(data, name) {
`将需要导出的数据转换为工作表worksheet`
const worksheet = xlsx.utils.json_to_sheet(data)
`创建一个新的工作簿workbook,用于存储工作表worksheet`
const workbook = xlsx.utils.book_new()
`将工作表worksheet添加到工作簿workbook中,并指定工作表的名称为Sheet1`
xlsx.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
`将工作簿workbook写入二进制数据excelBuffer,并指定生成的Excel文件类型为xlsx`
const excelBuffer = xlsx.write(workbook, { bookType: 'xlsx', type: 'array' })
`创建一个blob对象,用于表示Excel文件的二进制数据,type为Excel文件的MIME类型`
const blob = new Blob([excelBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
`使用saveAs函数将Blob对象保存为文件`
saveAs(blob, name)
}
}
}
</script>
以下为excel
导出结果(确认过眼神,是我们需要导出的excel
文件):
2. 前端将后端返回的二进制文件导出为excel
js
1.我们需要在接口请求中使用`responseType: 'blob'`, 来获取后端返回的二进制文件
2.封装公共方法`downloadBlob`:
downloadBlob(blob, fileName) {
`根据所提供的url地址,创建对象URL, 存储在内存中`
const blobUrl = URL.createObjectURL(blob)
`创建超链接标签link`
const link = document.createElement('a')
`将超链接标签link的跳转指向blobUrl`
link.href = blobUrl
`为超链接标签link下载的文件重命名`
link.download = fileName || '下载文件'
`触发超链接标签的点击事件,开始下载`
link.click()
`因为是用浏览器内存开辟的地址,所以需要及时释放对象URL,否则会一直占用系统内存,导致死机等严重影响性能的事发生`
URL.revokeObjectURL(blobUrl)
}
3. 使用封装好的公共方法:
async exportHandler(row) {
const res = await declareApi.matchExport({
batchIds: [row.id]
})
this.downloadBlob(res, `${row.batchCode}_${row.expressCompanyName}`)
}
c. excel
转换为html
(主要利用xlsx.utils.sheet_to_html
这个api
)
js
<template>
<div class="app-container system-home">
<el-upload
action="#"
:auto-upload="false"
accept=".xlsx,.xls"
:show-file-list="false"
:on-change="onChange"
>
<el-button size="small" type="primary">上传excel文件</el-button>
</el-upload>
<h4 class="mb10">excel展示:</h4>
<div ref="excelRef"></div>
</div>
</template>
<script>
import * as xlsx from 'xlsx'
export default {
data() {
return {
excelData: []
}
},
methods: {
async onChange(file) {
`两种方案皆可`
`1. 非promise版`
const reader = new FileReader()
reader.onload = (event) => {
let workbook = xlsx.read(event.target.result, { type: 'array', cellDates: true })
let worksheet = workbook.Sheets[workbook.SheetNames[0]]
this.$refs.excelRef.innerHTML = xlsx.utils.sheet_to_html(worksheet)
}
reader.readAsArrayBuffer(file.raw)
`2. promise版(同a方向的代码)`
let dataBinary = await new Promise((resolve) => {
let reader = new FileReader()
reader.readAsBinaryString(file.raw)
reader.onload = (ev) => {
resolve(ev.target.result)
}
})
let workBook = xlsx.read(dataBinary, { type: 'binary', cellDates: true })
let firstWorkSheet = workBook.Sheets[workBook.SheetNames[0]]
this.$refs.excelRef.innerHTML = xlsx.utils.sheet_to_html(firstWorkSheet)
}
}
}
</script>
Tips:
xlsx.read
的文件格式,需要与FileReader
读取的文件格式保持一致。
结语
往期精彩推荐(强势引流):
大概就这样吧。具有复杂表头的excel
文件解析,会在后续抽空研究~
更多精彩文章正在快马加鞭创作中,敬请期待哦~