一 纯前端实现方式①
如果数据量很小,并且没有什么处理逻辑的话,可以使用该种方式,用到的包是file-saver
<div style="padding-top: 30px;">
<el-button type="primary" @click="exportData">导出数据</el-button>
</div>
<el-table ref="multipleTableData" :data="tableData" :stripe="true">
<el-table-column type="selection" min-width="2" :reserve-selection="true" align="center" />
<el-table-column :resizable="false" prop="name" label="学生姓名" align="center" />
<el-table-column :resizable="false" prop="age" label="年龄" align="center" />
<el-table-column :resizable="false" prop="area" label="地区" align="center" />
</el-table>
<script>
import fileSaver from 'file-saver'
// 导出数据
exportData() {
const dataArray = this.$
(dataArray, 'dataArray')
let dataString = `姓名\t年龄\t所在省市\n` // 表头文字
for (let i = 0; i < ; i++) {
for (const key in dataArray[i]) {
dataString += `${dataArray[i][key] + '\t'}` // 获取到每一行数据后加上换行符进行拼接
}
dataString += '\n'
}
const blob = new Blob([dataString], { type: 'application/-excel' })
const time = () // 给表格名加个时间戳进行区分
const filename = '学生信息表' + time + '.xls'
(blob, filename)
}
</script>
该方法的核心是将每行数据+'\n'与表头拼接成字符串,然后利用Blob解析,最后利用file-saver包的saveAs方法保存成excel;
Blob表示二进制类型的大对象,可以看做是存放二进制数据的容器,此外,还可以通过Blob设置二进制数据的MIME类型;
var blob = new Blob(dataArr:Array<any>, opt:{type:string}); // 构造Blob函数
dataArray表示一个数组,包含了要添加到Blob对象中的数据,opt表示一个对象,用于设置Blob对象的属性(如:MIME类型)
创建出来的Blob对象包含有两个属性:size和type,size表示数据的大小(以字节为单位),type是MIME类型的字符串;
二 纯前端实现方式②
还是利用Blob实现,采用动态创建a标签的方式
<script>
// 导出数据
exportData() {
const dataArray = this.$
(dataArray, 'dataArray')
let dataString = `姓名\t年龄\t所在省市\n` // 表头文字
for (let i = 0; i < ; i++) {
for (const key in dataArray[i]) {
dataString += `${dataArray[i][key] + '\t'}` // 获取到每一行数据后加上换行符进行拼接
}
dataString += '\n'
}
const blob = new Blob([dataString], { type: 'application/-excel' })
const time = () // 给表格名加个时间戳进行区分
const filename = '学生信息表' + time + '.xls'
const link = ('a') // 创建a标签
= filename // 文件名
= 'none'
= (blob) // 创建URL对象
(link) // 在body中添加a标签
()
() // 主动释放URL对象
(link) // 移除a标签
}
</script>
其中,()静态方法会创建一个DOMString,其中包含一个表示参数中给定的对象的URL,这个URL的生命周期和创建它的窗口中的document绑定。这个新的URL对象表示指定的File对象或Blob对象,用于指定源object的内容;
在每次调用createObjectURL()方法时,都会创建一个新的URL对象,即使你已经用相同的对象作为参数创建过。当不再需要这些URL对象时,每个对象必须通过调用()方法来释放。浏览器在document卸载的时候,会自动释放它们,但是为获得最佳性能和内存使用状况,应该在安全的时机主动释放掉它们。
三 前后端配合
如果导出的数据很多或者数据要进行处理才能导出的话,此时用这种方法较为适合;
方式一:将数据及文件的格式从后端定义好,返回给前端一个链接,前端可以通过点击链接进行导出,使用a标签或者即可;
= 'url' // 或
<a href='url'></a>
但该方式无法携带token传递,对于需要使用身份校验的项目不是很好,除非将token封装在url中进行传递;
方法二:将后端传过来的二进制流文件进行解析,前端模拟出下载动作,进行文件导出;
exportData() {
const data = {
name: , // 姓名
age: , // 年龄
area: // 省市
}
exportDataAPI(data).then(response => {
if (response) {
const xlsx = 'application/-excel' // 导出格式为xlsx格式,前后端保持一致
const blob = new Blob([response], { type: xlsx })
const a = ('a') // 转换完成,创建一个a标签用于下载
const time = ()
= '学生信息表' + time + '.xlsx'
= (blob)
()
()
} else {
('导出失败')
}
}).catch(() => {
('失败')
})
}
其中data为前端传给后端接口的参数
exportDataAPI为封装的get或post请求,在封装时一定要注意将responseType设置为‘blob’,这样导出的文件内容才不会乱码;
export function exportDataAPI(data) {
return axios({
// post请求
url: '/export',
method: 'post',
params: data,
header: {
headers: { 'Content-Type': 'application/x-download' }
},
responseType: 'blob'
})
}
export function exportDataAPI() {
// get请求
return axios({
url: '/export',
method: 'get',
header: {
headers: { 'Content-Type': 'application/x-download' }
},
responseType: 'blob'
})
}
参考链接Vue前端下载Excel文件乱码汇总_带着希望活下去的博客-****博客_vue下载文件流乱码