前言
在我们实际开发过程中经常会遇到前端用来下载excel文件和上传解析excel文件,笔者最近刚好遇到了此类需求,中途并不顺利。所以总结分享下此次经历。
背景
首先,笔者增加这个需求的项目是vue2的后台管理。完整需求是支持纯前端下载csv文件和excel文件,同时也要支持前端解析上传之后的csv文件和excel将数据处理为数组扔给后端。
实现
首先先安装一个依赖xlsx.js用来解析excel或者csv格式文件非常好用
安装:
npm install xlsx -s
使用xlsx:
import XLSX from 'xlsx'
ok准备工作已经完成现在开始撸功能首先先写下载功能
//html代码
<el-button type="text" @click="downloadFile('csv')">下载文件 </el-button>
downloadFile(type) {
let fileData = ''
if (type === 'csv') {
let csvData = [
['列1', '列2', '列3'],
['1', 2, 3, ]
]
//此句话之所以多了\uFEFF处理是为了处理兼容性处理,避免导出的文件office打开失败
const rows = '\uFEFF' + csvData.map((row) => row.join(',')).join('\n')
//此处是为了保证编码格式不出现乱码
const blob = new Blob([rows], { type: 'text/csv;charset=utf-8;' })
fileData = URL.createObjectURL(blob)
} else {
fileData = require('./下载文件.xlsx')//此处放正常的模板Excel文件即可
}
// 创建虚拟链接并模拟点击下载操作
const link = document.createElement('a')
link.href = fileData
link.download = '文件名称' //不能为空不然下载文件名称为随机生成或者源文件名称
link.click()
},
至此导出功能完成下面就是解析表格文件功能,因为笔者是vue2技术栈所以上传组件是基于ele-ui的上传组件
//因为本地解析不需要跟后端交互
<el-upload class="avatar-uploader"
:before-upload="beforeAvatarUpload">
</el-upload>
js代码
//上传前函数
async handleUpload(file) {
this.uploadLoading = true
// 模拟上传过程,等待1秒钟
await new Promise((resolve) => setTimeout(resolve, 1000))
// 获取上传的文件,并将其转换成Base64编码的字符串
if (file.type === 'text/csv') {
// 处理csv
this.analyzeCsvFile(file)
} else {
// 处理excel
this.analyzeExcelFile(file)
}
return new Promise((resolve, reject) => {
reject()
})
},
// 处理上传是Excel文件
analyzeExcelFile(file) {
const fileReader = new FileReader()
fileReader.readAsBinaryString(file)
fileReader.onload = (ev) => {
try {
let workbook = XLSX.read(ev.target.result, {
type: 'binary'
})
let workSheets = workbook.Sheets[workbook.SheetNames[0]]
const jsonData = XLSX.utils.sheet_to_json(workSheets, { header: 1 })
console.log(jsonData,'excelData')
} catch (e) {
console.log(e)
}
}
},
//处理是csv格式
analyzeCsvFile(file) {
const fileReader = new FileReader()
fileReader.readAsText(file)
fileReader.onload = (ev) => {
try {
let csvData = []
//处理解析之后的csv格式
let result = ev.target.result.split('\n')
csvData = result.map((item) => {
let arr = item.split(',')
return arr
})
console.log(csvData,'csvData')
} catch (e) {
console.log(e)
}
}
},
至此整个纯前端上传下载Excel和csv文件功能全部完成了。
后话
此功能很常见,但是此次本人开发时候百度时发现很多文章都是相互引用或者年代久远导致一些文章上写的代码比葫芦画瓢之后自测不通过,浪费了很多时间,所以在此总结一下,一是为了加深记忆,二是为了避免其他小伙伴少踩一些坑。同时分享一个网站检测文件格式非常好用,用来检测你导出的文件格式是否正确。至此本次分享到此结束,如果有其他想法、建议、之巅欢迎大家在评论区交流。