新增excel导出
This commit is contained in:
parent
1c6d61da6b
commit
a6abe9ced8
15
README.md
15
README.md
|
|
@ -42,20 +42,5 @@ vue3.0 + Typescript + vuex + vue-router + Element-Plus scss
|
|||
- 退出
|
||||
- 其他各组件
|
||||
|
||||
## 开发
|
||||
```
|
||||
# 克隆项目
|
||||
git clone https://github.com/zouzhibin/vue-admin-perfect.git
|
||||
|
||||
# 安装依赖
|
||||
yarn install
|
||||
|
||||
# 本地开发 启动项目
|
||||
yarn serve
|
||||
```
|
||||
|
||||
### 发布
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@ const excelRouter = {
|
|||
name: 'upload-excel',
|
||||
meta: { title: '上传 Excel', noCache: true }
|
||||
},
|
||||
{
|
||||
path: 'upload-style-excel',
|
||||
component: () => import('@/views/excel/export-style-excel.vue'),
|
||||
name: 'upload-style-excel',
|
||||
meta: { title: '自定义样式导出 Excel', noCache: true }
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const othersRouter = {
|
|||
redirect: 'noRedirect',
|
||||
name: 'other',
|
||||
meta: {
|
||||
title: '扩展',
|
||||
title: '扩展组件',
|
||||
icon: 'management'
|
||||
},
|
||||
children: [
|
||||
|
|
|
|||
|
|
@ -63,6 +63,88 @@ export const exportExcel = async ({column,data,filename,autoWidth,format})=>{
|
|||
window.URL.revokeObjectURL(link.href); // 释放内存
|
||||
}
|
||||
}
|
||||
export function addCellStyle(cell, attr) {
|
||||
const {color, fontSize, horizontal, bold} = attr || {};
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
cell.fill = {
|
||||
type: 'pattern',
|
||||
pattern: 'solid',
|
||||
fgColor: {argb: color},
|
||||
};
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
cell.font = {
|
||||
bold: bold ?? true,
|
||||
size: fontSize ?? 11,
|
||||
// italic: true,
|
||||
// name: '微软雅黑',
|
||||
color: {argb: 'ff0000'},
|
||||
};
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
cell.alignment = {vertical: 'middle', wrapText: true, horizontal: horizontal ?? 'left'};
|
||||
}
|
||||
|
||||
export const exportStyleExcel =async ({column,data,filename,autoWidth,format})=>{
|
||||
// 创建excel
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
// 设置信息
|
||||
workbook.creator = "Me";
|
||||
workbook.title = filename;
|
||||
workbook.created = new Date();
|
||||
workbook.modified = new Date();
|
||||
// 创建工作表
|
||||
const worksheet = workbook.addWorksheet(filename);
|
||||
// 设置列名
|
||||
let columnsName = [];
|
||||
column.forEach((item,index)=>{
|
||||
let obj = {
|
||||
header: item.label, key:item.name, width: null
|
||||
}
|
||||
if(autoWidth){
|
||||
let maxArr = [autoWidthAction(item.label)]
|
||||
data.forEach(ite=>{
|
||||
let str = ite[item.name] ||''
|
||||
if(str){
|
||||
maxArr.push(autoWidthAction(str))
|
||||
}
|
||||
})
|
||||
obj.width = Math.max(...maxArr)+5
|
||||
}
|
||||
// 设置列名、键和宽度
|
||||
columnsName.push(obj);
|
||||
})
|
||||
worksheet.columns = columnsName;
|
||||
// 添加行
|
||||
worksheet.addRows(data);
|
||||
// 写入文件
|
||||
|
||||
// 设置表头颜色
|
||||
// 给表头添加背景色。因为表头是第一行,可以通过 getRow(1) 来获取表头这一行
|
||||
const headerRow = worksheet.getRow(1);
|
||||
// 通过 cell 设置样式,更精准
|
||||
headerRow.eachCell((cell) => addCellStyle(cell, {color: 'dff8ff', fontSize: 12, horizontal: 'left'}));
|
||||
|
||||
const uint8Array =
|
||||
format === "xlsx"
|
||||
? await workbook.xlsx.writeBuffer()
|
||||
: await workbook.csv.writeBuffer();
|
||||
|
||||
const blob = new Blob([uint8Array], { type: "application/octet-binary" });
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
// msSaveOrOpenBlob方法返回boolean值
|
||||
navigator.msSaveBlob(blob, filename + `.${format}`);
|
||||
// 本地保存
|
||||
} else {
|
||||
const link = document.createElement("a"); // a标签下载
|
||||
link.href = window.URL.createObjectURL(blob); // href属性指定下载链接
|
||||
link.download = filename + `.${format}`; // dowload属性指定文件名
|
||||
link.click(); // click()事件触发下载
|
||||
window.URL.revokeObjectURL(link.href); // 释放内存
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 默认的列宽
|
||||
export const DEFAULT_COLUMN_WIDTH = 20;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<div>
|
||||
<div style="margin-bottom: 15px;display: flex;align-items: center">
|
||||
<el-input v-model="input" placeholder="请输入文件名" style="width: 200px;margin-right: 10px"/>
|
||||
<el-button @click="exportExcelAction" type="primary">
|
||||
<el-icon style="margin-right: 10px"><document-remove /></el-icon>导出样式 Excel
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="list" style="width: 100%" border>
|
||||
<template v-for="item,index in column" :key="index">
|
||||
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
||||
</template>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref,reactive} from "vue";
|
||||
import * as dayjs from 'dayjs'
|
||||
import { ElMessage,ElMessageBox } from 'element-plus'
|
||||
import {exportStyleExcel} from '@/utils/exprotExcel'
|
||||
const data = []
|
||||
for(let i=0;i<10;i++){
|
||||
data.push({
|
||||
date: '2016-05-02',
|
||||
name: '王五'+i,
|
||||
price: 1+i,
|
||||
province: '上海',
|
||||
admin:"admin",
|
||||
sex:i%2?1:0,
|
||||
checked:true,
|
||||
id:i+1,
|
||||
age:0,
|
||||
city: '普陀区',
|
||||
address: '上海市普上海',
|
||||
zip: 200333
|
||||
})
|
||||
}
|
||||
const column = [
|
||||
{ name: 'id', label: 'id', },
|
||||
{ name: 'name',
|
||||
label: '姓名',
|
||||
inSearch:true,
|
||||
valueType:'input',
|
||||
},
|
||||
{ name: 'age',
|
||||
label: '年龄',
|
||||
align:'right',
|
||||
},
|
||||
{ name: 'sex',
|
||||
label: '性别',
|
||||
slot:true,
|
||||
inSearch:true,
|
||||
options:[{
|
||||
value:1,
|
||||
label:'男'
|
||||
},{
|
||||
value:0,
|
||||
label:'女'
|
||||
}],
|
||||
valueType:'select',
|
||||
},
|
||||
{
|
||||
name: 'price',
|
||||
label: '价格',
|
||||
inSearch:true,
|
||||
valueType:'input',
|
||||
},
|
||||
{ name: 'admin', label: '账号', inSearch:true,
|
||||
valueType:'input',},
|
||||
{ name: 'address', label: '地址', inSearch:true,
|
||||
valueType:'input', },
|
||||
{ name: 'date', label: '日期',sorter:true, inSearch:true,
|
||||
valueType:'input', },
|
||||
{ name: 'province', label: '省份' },
|
||||
{ name: 'city', label: '城市' },
|
||||
{ name: 'zip', label: '邮编' },
|
||||
]
|
||||
const list = ref(data)
|
||||
const input = ref('')
|
||||
const format = ref('xlsx')
|
||||
const exportExcelAction = ()=>{
|
||||
exportStyleExcel({
|
||||
column,
|
||||
data,
|
||||
filename:input.value||'导出 excel',
|
||||
format:format.value,
|
||||
autoWidth:true
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
style="width: 100%"
|
||||
class="upload-demo"
|
||||
drag
|
||||
action="/"
|
||||
:before-upload="beforeUploadAction"
|
||||
type="file" accept=".xlsx, .xls"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,5 @@
|
|||
<template>
|
||||
<div class="login-container">
|
||||
<!-- <video-->
|
||||
<!-- poster="@/assets/mp4/3.jpeg"-->
|
||||
<!-- loop-->
|
||||
<!-- autoplay-->
|
||||
<!-- muted-->
|
||||
<!-- >-->
|
||||
<!-- <source src="@/assets/mp4/2.mp4">-->
|
||||
<!-- </video>-->
|
||||
|
||||
<!-- <img src="@/assets/3.png" class="bg"/>-->
|
||||
<div class="login-box">
|
||||
<!--登录功能-->
|
||||
<div style="color: white;text-align: center;margin-bottom: 15px">登录系统-密码账号随便填 admin admin</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue