前言
Excel格式在大家看来并不陌生,项目工作中经常会用到将某个表格中的数据,或者是后端传输的数据,作为一个Excel文件进行导出保存。接下来讲下如何通过'file-saver'依赖包实现Excel文件导出、下载模板和上传需求的。
需求如下:
需求是这里有一个员工列表数据需要通过点击右上方的'excel导入' 'excel导出' 按钮实现,并且发送导出的请求后端返回的是一个二进制文件流。
根据接口文档分别封装好三个API:
// 导入员工(上传excel)
export const importFile = (data) => {
return request({
url: '/sys/user/import',
method: 'POST',
data // 后端要data的值是'form-data'格式
})
}
// 下载导入员工
export const importTemplate = () => {
return request({
url: '/sys/user/import/template',
// 如果后端明确表示返回的是二进制文件流,这儿要通过下面代码告诉 axios
responseType: 'blob'
})
}
// 导出员工excel
export const exportEmployee = () => {
return request({
url: '/sys/user/export'
// 如果后端明确表示返回的是二进制文件流,这儿要通过下面代码告诉 "xios responseType: 'blob'"
})
}
导出excel按钮:
1.终端安装依赖包
npm i file-saver //安装'file-saver'依赖包
2.设置响应拦截器
// 2.2 响应拦截器
request.interceptors.response.use(res => {
// 因为返回的是二进制,因此需要判断一下如果是二进制,直接返回res.data
if (res.data instanceof Blob) return res.data
...
}
<el-row class="opeate-tools" type="flex" justify="end">
<el-button size="mini" @click="exportExcel">excel导出</el-button> //绑定按钮的点击事件
</el-row>
<script>
import { exportEmployee } from '@/api/employee' //导入封装好的导出员工接口函数
import { saveAs } from 'file-saver' //按需从'file-saver'依赖包 导入saveAs储存文件
methods: {
async exportExcel() {
// const r = await exportEmployee() //通过点击事件调用导出excel接口api
// console.log(r)
saveAs(await exportEmployee(), '员工信息.excel') //通过依赖包
},
</script>
下载导入员工模板:
<el-dialog width="500px" title="员工导入" :visible="showExcelDialog" @close="$emit('update:showExcelDialog', false)">
<el-button type="text" @click="downloadTemplate">下载导入模板</el-button>
</el-dialog>
<script>
import { saveAs } from 'file-saver' //按需从'file-saver'依赖包 导入saveAs储存文件
import { importTemplate } from '@/api/employee' //导入封装好的下载导入员工模板接口api
export default {
props: {
showExcelDialog: { //接收父组件的弹窗传值
type: Boolean,
default: false
}
},
methods: {
async downloadTemplate() { //点击下载模板按钮
saveAs(await importTemplate(), '下载模板.excel') //调用下载excel模板请求,执行下载
},
}
}
</script>
导出员工excel:
<el-dialog width="500px" title="员工导入" :visible="showExcelDialog" @close="$emit('update:showExcelDialog', false)">
<input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="uploadchang">
<span>将文件拖到此处或
<el-button type="text" @click="uploadFiel">点击上传</el-button>
</span>
</el-dialog>
<script>
import { saveAs } from 'file-saver' //按需从'file-saver'依赖包 导入saveAs储存文件
import { importTemplate } from '@/api/employee' //导入封装好的下载导入员工模板接口api
export default {
props: {
showExcelDialog: { //接收父组件的弹窗传值
type: Boolean,
default: false
}
},
methods: {
uploadFiel() {
//如何拿到到文件信息?
//点击普通的上传按钮的时候,找到'file dom',主动触发它的点击,监听原生'input file' 的 change事件,在change回调中就可以拿到文件信息
this.$refs['excel-upload-input'].click() //找到'file dom',主动触发它的点击,
},
async uploadchang(e) {
const file = e.target.files[0] // 取[0]下标,第一个上传的文件
if (file) {
try {
// 1.转换为formData格式
const form = new FormData()
// name是后端固定的'file',value值就是文件信息
form.append('file', file)
// 2.上传到后端
await importFile(form)
// 3.前端更新数据
this.$emit('getDepartments')
// 4.关闭弹窗
this.$emit('update:showExcelDialog', false)
// 5.成功提示信息
this.$message.success('导入成功')
} catch (e) {
console.log(e)
} finally {
// 注意:需要把input file框中的 value文件清空,防止两次上传同一个文件,不触发@change事件
this.$refs['excel-upload-input'].value = ''
}
}
}
}
}
</script>
结尾
此文章主要针对后端返回的二进制文件流,同时需要输出的是Excel格式输出Excel文件的导出、下载模板和上传需求(仅供参考交流)。
注意点:两次上传同一个文件的时候,不会触发@chang事件,需要将'input file'框中的value值清空掉。