一、首先实现动态列,为了防止刷新恢复初始状态,用pinia持久化存储
实现效果:
实现代码:
//主页面代码
//template
<el-button type="primary" @click="selectDialogRef.openDialog()"> 简表设置 </el-button>
<el-table :data="dataList">
<el-table-column v-if="isShowColums('chineseName')" prop="chineseName" label="企业中文全称"/>
// .... 剩下的列以此类推 都用isShowColums传入绑定的属性名控制显示隐藏
</el-table>
<select-dialog ref="selectDialogRef"></select-dialog>
//js
import { xxxStore } from '/@/stores/xxxList'; // 替换自己的仓库名
const SelectDialog = defineAsyncComponent(() => import('./select.vue'));
const selectDialogRef = ref();
//控制列展示
function isShowColums(field: string) {
return xxxStore().$state.xxxList.findIndex((a: string) => a == field) != -1;
// findIndex找不到的话是-1 则会返回false 同理找到则为true
}
// 弹框插件子组件代码
<template>
<el-dialog title="简表设置" v-model="visible" :close-on-click-modal="false" draggable>
<!-- 列选择器 -->
<el-checkbox-group v-model="selectedColumn">
<el-checkbox v-for="col in columns" :key="col.prop" :label="col.prop">{{ col.label }}</el-checkbox>
</el-checkbox-group>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { xxxStore } from '/@/stores/xxxList';
const xxx = xxxStore();
const loading = ref(false);
const visible = ref(false);
const selectedColumn = ref([]);
const columns = [
// 这里写入表格对应的字段和中文名称
{ label: '企业中文全称', prop: 'chineseName' },
{ label: '组织机构代码', prop: 'organizationCode' },
......
];
// 打开弹窗
const openDialog = () => {
visible.value = true;
// 从仓库内获取表格展示信息
selectedColumn.value = xxx.$state.xxxList;
};
// 提交
const onSubmit = async () => {
try {
loading.value = true;
xxx.changeList(selectedColumn.value);
useMessage().success('设置成功');
visible.value = false;
} catch (err: any) {
console.error(err.msg);
} finally {
loading.value = false;
}
};
// 暴露变量
defineExpose({
openDialog,
});
</script>
//pinia仓库代码
//确认下载了pinia
import { defineStore } from 'pinia';
/**
* 创建并导出字典存储的 Vue3 store 对象
* @function
*
*/
export const xxxStore = defineStore('xxxList', {
state: () => ({
//这里是设置默认展示的列
xxxList: [
'chineseName',
'organizationCode',
......
],
}),
actions: {
getEnterpriseList() {
return this.enterpriseList;
},
changetList(list: []) {
//先清除再录入 防止数据一直加 当然可以用set处理 我不太精通就没用
this.xxxList = [];
this.xxxList = list;
},
},
persist: {
enabled: true, // 这个配置代表存储生效,而且是整个store都存储
},
});
二、导出文件 后端给了接口 把选中的对象数组和选中的字段数组传给后端就可以返回文件流
实现效果:
实现代码
//template
<el-button type="primary" @click="exportExcel"> 导出 </el-button>
<el-table
:data="dataList"
@selection-change="selectionChangHandle"
>
</el-table>
//js
const columns = [
// 与子组件一样的数据列 这里使用主要是为了后端要中文字段
{ label: '企业中文全称', prop: 'chineseName' },
{ label: '组织机构代码', prop: 'organizationCode' },
........
];
// 多选事件
const selectionChangHandle = (objs:[]) => {
// 拿到选中对象数组
selectObj.value = objs;
};
// 导出excel
const exportExcel = () => {
// 中文字段名
const newArray = xxxStore().$state.xxxList.map((prop) => {
const column = columns.find((item) => item.prop === prop);
return column ? column.label : null;
});
// 中文对象数组---保留原有字段顺序---这里是为了防止导出之后不按页面上表头顺序排列
const selectArray = selectObj.value.map((item) => {
const newItem = {};
columns.forEach((column) => {
const key = column.prop;
if (item.hasOwnProperty(key)) {
newItem[column.label] = item[key];
}
});
return newItem;
});
// 过滤对象数组只保留需要的字段
const filteredDataArray = selectArray.map((item) => {
return newArray.reduce((acc, prop) => {
if (item.hasOwnProperty(prop)) {
acc[prop] = item[prop];
}
return acc;
}, {});
});
//调用接口
xxxApi({ fieldNames: newArray, data: filteredDataArray }).then((response) => {
handleBlobFile(response, '示例.xlsx'); //
});
};
function handleBlobFile(response: any, fileName: string) {
// 处理返回的文件流
const blob = response;
console.info(blob);
if (blob && blob.size === 0) {
useMessage().error('内容为空,无法下载');
return;
}
// debugger;
if (blob.type === 'application/json') {
//说明有问题了
blob.text().then((text:any) => {
const jsonData = JSON.parse(text);
// 现在,jsonData 是一个 JSON 对象
if (jsonData.code === 1) {
useMessage().error(jsonData.msg);
}
});
}
const link = document.createElement('a');
// 兼容一下 入参不是 File Blob 类型情况
var binaryData = [] as any;
binaryData.push(response);
link.href = window.URL.createObjectURL(new Blob(binaryData));
link.download = fileName;
document.body.appendChild(link);
link.click();
window.setTimeout(function () {
// @ts-ignore
URL.revokeObjectURL(blob);
document.body.removeChild(link);
}, 0);
}
标签:xlsx,const,列及,value,prop,item,xxxList,return,element
From: https://blog.csdn.net/2401_82730858/article/details/139653420