在做一些后台管理系统中,经常会遇到table 组件;然后需要导出excel.开发中实现方法如下:
第一类:后端来做导出功能(后端做更合适)
1. 后端生成excel,返回一个url地址;前端直接利用浏览器下载
2.后端接口返回二进制流文件,前端处理流文件(参见:二进制流文件下载_卡卡罗特的博客-CSDN博客)
第二类:前端来做导出工作
1. 安装相关现有的插件来处理:xlsx file-saver(自行百度)
2. 这里记录一下,自己见到一种新方法,前端自己生文件下载;这里就用到encodeURIComponent() 函数;
定义和用法
encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。
其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
语法
encodeURIComponent(uri)
数不多说上代码,定义导出数据格式:
//导出excel的数据
exportJsonData: {
tHeader: [], //表头中文例如 ["时间",“名称”, “金额”]
filterVal: [], //表头key例如 ["time", "name", "money"]
list: [], //表格数据
total_info: '' //总计信息数据,可以没有为空,表格顶部做统计使用
},
后端获取的数据,自己需要整理一下exportCsv(),形成上面的结构:然后执行下载方法exportPathMethod(),导出表格字段信息格式,可以自己参函数内部配置。文件后缀名称自己定义
csv可以改成 xlsx
// 导出表格数据处理
exportCsv(){
// 整合数据
let { dataList, tableHeader } = this;
if(dataList.length < 1 || tableHeader.length < 1) {
this.$message.error("暂无数据");
return false;
}
let tHeader = tableHeader.map(item => item.label);
let filterVal = tableHeader.map(item => item.key);
this.exportJsonData.tHeader = tHeader //表头中文
this.exportJsonData.filterVal = filterVal; //表头key
this.exportJsonData.list = dataList; //表体数据
// 执行导出方法
this.exportPathMethod(this.exportJsonData, "账单报表");
},
//导出数据组合
exportPathMethod(data, setName) {
/*
*注:csv文件:","逗号换列,\n换行,\t防止excel将长数字变科学计算法等样式
*/
//要导出的json数据
let mainLists = data; //主表
//## 数据处理
//一级表
let mainTitle = mainLists.tHeader; //一级标题
let mainTitleForKey = mainLists.filterVal; //一级过滤
let mainList = mainLists.list; //一级数据
let mainStr = [];
//当总计有,时替换
if (mainLists.total_info.indexOf(",") > -1) {
mainLists.total_info = mainLists.total_info.replace(/,/g, "")
}
mainStr.push(mainLists.total_info + "\n"); //总计信息:添加上换列转成字符串并存进数组
mainStr.push(mainTitle.join(",") + "\n"); //标题添加上换列转成字符串并存进数组
console.log(" mainList mainTitleForKey", mainList, mainTitleForKey)
mainList.forEach(e => {
let temp = [];
mainTitleForKey.forEach(f => {
if (f.indexOf(".") > -1) { //当有.时
temp.push(
e[f.split(".")[0]][
f.split(".")[1]
]
); //根据过滤器拿出对应的值
} else if (Array.isArray(e[f])) { //当是数组时
let s = e[f].join(' ')
temp.push(s); //根据过滤器拿出对应的值
} else if (e[f] && (typeof (e[f]) == 'string') && e[f].indexOf(',') > -1) { //当有逗号时
let s = e[f].replace(/,/g, "")
temp.push(s); //根据过滤器拿出对应的值
} else if (!isNaN(e[f])) { //当是数字时
let s = "¥" + e[f];
temp.push(s); //根据过滤器拿出对应的值
} else {
temp.push(e[f]); //根据过滤器拿出对应的值
}
})
console.log(" temp temp", temp)
mainStr.push(temp.join(",") + "\n"); //取出来的值加上逗号换列转字符串存数组
})
//两个表数组转成字符串合并
let merged = mainStr.join("");
//## 导出操作
// encodeURIComponent解决中文乱码
const uri =
"data:text/csv;charset=utf-8,\ufeff" +
encodeURIComponent(merged);
// 通过创建a标签实现
let link = document.createElement("a");
link.href = uri;
// 对下载的文件命名
link.download = setName + `.csv`;
document.body.appendChild(link);
link.click();
},