feat: base 所有表格增加通用导出方法
This commit is contained in:
parent
a0814191a7
commit
48ea04138b
|
|
@ -45,6 +45,14 @@
|
|||
</el-button>
|
||||
<el-button v-if="!hideRefresh" @click="reload" icon="el-icon-refresh-right" circle style="margin-left: 15px">
|
||||
</el-button>
|
||||
<el-popover v-if="!hideExport" placement="top" trigger="click" :hide-after="0">
|
||||
<template #reference>
|
||||
<el-button icon="el-icon-download" circle style="margin-left: 15px"></el-button>
|
||||
</template>
|
||||
<div><el-button type="primary" size="small" @click="exportExcel(0)">1导出本页数据</el-button></div>
|
||||
<div style="margin-top: 2px;" v-if="hExportExcel"><el-button type="primary" size="small" @click="exportExcel(1)">2导出本页数据</el-button></div>
|
||||
<div style="margin-top: 2px;" v-if="hExportExcel"><el-button type="primary" size="small" @click="exportExcel(2)">3导出全部数据</el-button></div>
|
||||
</el-popover>
|
||||
<el-popover v-if="column" placement="top" title="列设置" :width="500" trigger="click" :hide-after="0"
|
||||
@show="customColumnShow = true" @after-leave="customColumnShow = false">
|
||||
|
||||
|
|
@ -82,7 +90,7 @@
|
|||
import config from "@/config/table";
|
||||
import columnSetting from "./columnSetting";
|
||||
import { genTree } from "@/utils/verificate";
|
||||
|
||||
import { domToExcel } from "@/utils/exportExcel";
|
||||
export default {
|
||||
name: "scTable",
|
||||
components: {
|
||||
|
|
@ -115,6 +123,8 @@ export default {
|
|||
hideDo: { type: Boolean, default: false },
|
||||
hideRefresh: { type: Boolean, default: false },
|
||||
hideSetting: { type: Boolean, default: false },
|
||||
hideExport: { type: Boolean, default: false },
|
||||
hExportExcel: { type: Function, default: null },
|
||||
paginationLayout: { type: String, default: config.paginationLayout },
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -299,6 +309,35 @@ export default {
|
|||
this.getData();
|
||||
this.$emit("resetQuery");
|
||||
},
|
||||
//导出
|
||||
exportExcel(type=0) {
|
||||
if (type === 0) {
|
||||
try {
|
||||
domToExcel(this.$refs.scTable.$el, "表格数据");
|
||||
} catch (error) {
|
||||
console.error('导出失败:', error);
|
||||
this.$message.error("导出失败");
|
||||
}
|
||||
}
|
||||
else if (type === 1) {
|
||||
this.hExportExcel(this.tableData);
|
||||
}else if (type === 2) {
|
||||
var c = Object.assign({}, this.query, this.tableParams, {[this.orderStr]: this.order}, {page: 0})
|
||||
let ElLoading = this.$loading({
|
||||
lock: true,
|
||||
text: '数据请求中,请稍后...',
|
||||
background: 'rgba(0, 0, 0, 0)',
|
||||
})
|
||||
this.apiObj.req(c).then(res=>{
|
||||
ElLoading.close();
|
||||
this.hExportExcel(res);
|
||||
}).catch(err=>{
|
||||
ElLoading.close();
|
||||
console.log(err)
|
||||
this.$message.error("导出失败");
|
||||
})
|
||||
}
|
||||
},
|
||||
//自定义变化事件
|
||||
columnSettingChange(userColumn) {
|
||||
this.userColumn = userColumn;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
import * as XLSX from 'xlsx';
|
||||
|
||||
export const domToExcel = (dom, name="data") => {
|
||||
const worksheet = XLSX.utils.table_to_sheet(dom);
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet);
|
||||
XLSX.writeFile(workbook, `${name}.xlsx`);
|
||||
}
|
||||
/**
|
||||
* eg: .columns = [
|
||||
* { header: 'Id', key: 'id', wpx: 10 },
|
||||
|
|
@ -10,35 +17,83 @@ import * as XLSX from 'xlsx';
|
|||
* @param data 数据
|
||||
* @param name 文件名
|
||||
*/
|
||||
export const generateExcel = (columns = [], data = [], name = '') => {
|
||||
export const dataToExcel = (columns = [], data = [], name = 'data') => {
|
||||
const headers = columns.map((item) => item.header);
|
||||
const otherConfigs = columns.map(({ key, header, ...item }) => item);
|
||||
const dataList = data.map((item) => {
|
||||
let obj = {};
|
||||
columns.forEach((col) => {
|
||||
obj[col.header] = item[col.key];
|
||||
columns.forEach(col => {
|
||||
obj[col.header] = getNestedValue(item, col.key) ?? '';
|
||||
});
|
||||
return obj;
|
||||
});
|
||||
const workbook = XLSX.utils.book_new();
|
||||
workbook.SheetNames.push(name);
|
||||
// workbook.SheetNames.push(name);
|
||||
const worksheet = XLSX.utils.json_to_sheet(dataList, {
|
||||
header: headers,
|
||||
});
|
||||
worksheet['!cols'] = otherConfigs;
|
||||
workbook.Sheets[name] = worksheet;
|
||||
// 生成Blob数据
|
||||
const excelData = XLSX.write(workbook, { type: 'array', bookType: 'xlsx' });
|
||||
const blobData = new Blob([excelData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
// 创建Blob URL
|
||||
const blobUrl = URL.createObjectURL(blobData);
|
||||
// 创建一个隐藏的<a>标签并设置href属性为Blob URL
|
||||
const link = document.createElement('a');
|
||||
link.href = blobUrl;
|
||||
link.target = '_blank';
|
||||
link.download = `${name}.xlsx`;
|
||||
// 触发点击操作,开始下载文件
|
||||
link.click();
|
||||
// 释放Blob URL
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
// 自动计算列宽
|
||||
worksheet['!cols'] = calculateColumnWidths(columns, dataList);
|
||||
// const otherConfigs = columns.map(({ key, header, ...item }) => item);
|
||||
// worksheet['!cols'] = otherConfigs;
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet);
|
||||
XLSX.writeFile(workbook, `${name}.xlsx`);
|
||||
// workbook.Sheets[name] = worksheet;
|
||||
// // 生成Blob数据
|
||||
// const excelData = XLSX.write(workbook, { type: 'array', bookType: 'xlsx' });
|
||||
// const blobData = new Blob([excelData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
// // 创建Blob URL
|
||||
// const blobUrl = URL.createObjectURL(blobData);
|
||||
// // 创建一个隐藏的<a>标签并设置href属性为Blob URL
|
||||
// const link = document.createElement('a');
|
||||
// link.href = blobUrl;
|
||||
// link.target = '_blank';
|
||||
// link.download = `${name}.xlsx`;
|
||||
// // 触发点击操作,开始下载文件
|
||||
// link.click();
|
||||
// // 释放Blob URL
|
||||
// URL.revokeObjectURL(blobUrl);
|
||||
};
|
||||
|
||||
const getNestedValue = (obj, path, defaultValue = '') => {
|
||||
if (!obj || !path) return defaultValue;
|
||||
|
||||
const keys = path.split('.');
|
||||
let result = obj;
|
||||
|
||||
for (const key of keys) {
|
||||
if (result === null || result === undefined) {
|
||||
return defaultValue;
|
||||
}
|
||||
result = result[key];
|
||||
}
|
||||
|
||||
return result !== undefined ? result : defaultValue;
|
||||
};
|
||||
const calculateColumnWidths = (columns, dataList) => {
|
||||
// 确保 dataList 有数据
|
||||
if (!dataList || dataList.length === 0) {
|
||||
return columns.map(col => ({ wch: 15 })); // 返回默认宽度
|
||||
}
|
||||
|
||||
return columns.map(col => {
|
||||
// 固定宽度优先
|
||||
if (col.wpx) return { wpx: col.wpx };
|
||||
if (col.wch) return { wch: col.wch };
|
||||
if (col.width) return { wch: col.width };
|
||||
|
||||
const header = col.header || '';
|
||||
let maxWidth = header.length;
|
||||
|
||||
// 遍历数据计算最大宽度
|
||||
for (let i = 0; i < Math.min(dataList.length, 100); i++) {
|
||||
const item = dataList[i];
|
||||
// 确保使用正确的键名
|
||||
const value = item[header] !== undefined ? String(item[header]) : '';
|
||||
if (value.length > maxWidth) {
|
||||
maxWidth = value.length;
|
||||
}
|
||||
}
|
||||
|
||||
return { wch: Math.min(Math.max(maxWidth + 2, 8), 50) };
|
||||
});
|
||||
};
|
||||
Loading…
Reference in New Issue