文章引用,稍微修改了一下按钮显示方式Vue3 Element Plus表格导出(带图片导出)、导入功能_vue element plus 导出 excel-CSDN博客
1、下载依赖
npm install js-table2excel
npm install xlsx
2、下面就是全部代码
<template>
<el-upload action="#" :show-file-list="false" :before-upload="importBefore" accept=".xls,.xlsx"
style="margin: 0 12px;display: flex;align-items: center;">
<el-button type="success">导入</el-button>
</el-upload>
<el-dropdown style="margin-right: 10px;">
<el-button type="primary">
导出<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="allExport">全部导出</el-dropdown-item>
<el-dropdown-item @click="assignExport">批量导出</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-table border stripe size="small" highlight-current-row :data="tableData" :style="{height:contentHeight}" style="width: 100%" ref="multipleTableRef">
<el-table-column type="selection" width="40" v-if="permission.tableList.findIndex((v) => (v === '选中框')) < 0" />
<!-- <el-table-column label="序号" type="index" :index="indexMethod" width="55"
v-if="permission.tableList.findIndex((v) => (v === '序号')) < 0">
</el-table-column> -->
<el-table-column label="客户编码" >
<template #default="scope">
<div>{{ scope.row.Code }}</div>
</template>
</el-table-column>
<el-table-column label="客户名称" >
<template #default="scope">
<div>{{ scope.row.Name }}</div>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted, toRaw, toRefs, h } from 'vue'
import type { ElTable } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { ElButton, ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import table2Excel from 'js-table2excel' // 引入 js-table2excel
import * as XLSX from "xlsx" // 引入 xlsx
const ruleFormRef = ref<FormInstance>()
const multipleTableRef = ref<InstanceType<typeof ElTable>>()
//导入导出功能
const state = reactive({
exportConfig: [ // 导出Excel表格配置
{
title: '客户编码',
key: 'Code',
type: 'text'
},
{
title: '客户名称',
key: 'Name',
type: 'text'
},
/*
{ 导出图片这样配置,type为image
title: '头像',
key: 'avatar',
type: 'image'
},
*/
],
formatColumns: [ // 导出特殊字段处理
{
prop: 'age',
option: {
'1': '男',
'2': '女'
},
},
]
})
//表格
const tableData = ref()
const { exportConfig, formatColumns } = toRefs(state)
// 表格导出
// 选中数据导出
function assignExport() {
// getSelectionRows Element Plus table表格组件方法,获取当前选中的数据
let arr: any[] = multipleTableRef.value?.getSelectionRows()
if (!arr.length) {
return ElMessage({
message: '请选择需要导出的数据',
type: 'warning',
})
}
ElMessageBox.close() // 关闭弹出框
const loading = ElLoading.service({ // 打开遮罩层
lock: true,
text: '请稍等...',
background: 'rgba(255, 255, 255, 0.5)',
})
let list = JSON.stringify(arr)
list = formatExportData(JSON.parse(list))
// table2Excel(state.exportConfig, list, '导出数据') state.exportConfig导出表格配置,list导出数据列表,“导出数据”:导出文件名称
// console.log(list)
table2Excel(state.exportConfig, list, '客户列表')
loading.close() // 关闭遮罩层
}
// 所有数据导出
async function allExport() {
ElMessageBox.close() // 关闭弹出框
const loading = ElLoading.service({ // 打开遮罩层
lock: true,
text: '请稍等...',
background: 'rgba(255, 255, 255, 0.5)',
})
/*
const res = await userList()
这里是去调后台接口,拿到需要导出的所有数据
let list = formatExportData(res.data)
res.data:就是接口返回的数据
*/
if(tableData.value &&tableData.value.length > 0){
let list = JSON.stringify(tableData.value) // 这里直接用定义好的数据了
list = formatExportData(JSON.parse(list))
table2Excel(state.exportConfig, list, '客户列表')
}else{
ElMessage({
message: '暂无数据导出!',
type: 'warning',
})
}
loading.close() // 关闭遮罩层
}
function formatExportData(list) {
// 处理特殊字段
/*
比如:你请求的数据中的age返回的是1或者2,其1代表“男”2代表“女”
导出表格时,总不能以1和2的方式展示,此方法用于处理特殊字段
*/
list.forEach((item) => {
state.formatColumns.forEach((i) => {
item[i.prop] = i.option[item[i.prop]]
})
for (let key in item) {
if (!item[key] && item[key] == null) {
item[key] = ""
}
}
});
return list
}
// 表格导入
function importBefore(file) {
const reader = new FileReader();
reader.onload = (e) => {
const data = e.target?.result;
const workbook = XLSX.read(data, { type: "array" });
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
const results = XLSX.utils.sheet_to_json(worksheet);
importAdd(results)
};
reader.readAsArrayBuffer(file);
}
function importAdd(list) {
// 处理上传时excel中特殊字段
// 如:性别:男/女 不能以文字形式上传,此方法时将数据转为对应的值
list.forEach((item) => {
state.exportConfig.forEach((i) => {
item[i.key] = item[i.title]
delete item[i.title]
})
// 处理时间,在使用FileReader解析后的时间可能是这样的 44877.4284259259 就需要专为时间戳或者时间格式
for (let key in item) {
if (key == "date") {
// ExcelDateToJSDate(item[key]).getTime() // 返回时间戳 1668182400000 毫秒
// ExcelDateToJSDate(item[key]) 返回时间格式 Sat Nov 12 2022 10:17:39 GMT+0800 (中国标准时间) {}
// 注意:这个方法在转换的时间存在误差,误差在一分钟之内
item[key] = ExcelDateToJSDate(item[key])
}
}
})
list = convertImportData(list)
// list 返回上传的Excel文件,接下来掉后台接口批量添加就可以了。
console.log(list)
}
function ExcelDateToJSDate(serial) {
var utc_days = Math.floor(serial - 25569);
var utc_value = utc_days * 86400;
var date_info = new Date(utc_value * 1000);
var fractional_day = serial - Math.floor(serial) + 0.0000001;
var total_seconds = Math.floor(86400 * fractional_day);
var seconds = total_seconds % 60;
total_seconds -= seconds;
var hours = Math.floor(total_seconds / (60 * 60));
var minutes = Math.floor(total_seconds / 60) % 60;
return new Date(date_info.getFullYear(), date_info.getMonth(), date_info.getDate(), hours, minutes, seconds);
}
function convertImportData(list) {
list.forEach((item) => {
state.formatColumns.forEach((i) => {
for (let key in i.option) {
if (item[i.prop] == i.option[key]) {
item[i.prop] = key
}
}
})
for (let key in item) {
if (!item[key] && item[key] == undefined) {
item[key] = ""
}
}
});
return list
}
// 处理特殊表格字段展示
function fieldChange(row, option = { '1': '男', '2': '女' }) {
if (option[row]) {
return option[row]
}
}
</script>
<style lang="scss" scoped>
</style>