feat: 增加表格导出功能
This commit is contained in:
parent
8304970a59
commit
681b3144d1
@ -25,7 +25,8 @@
|
|||||||
"pinia": "^2.0.33",
|
"pinia": "^2.0.33",
|
||||||
"vite": "^4.2.1",
|
"vite": "^4.2.1",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
"vue-router": "^4.1.6"
|
"vue-router": "^4.1.6",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.4.4",
|
"@commitlint/cli": "^17.4.4",
|
||||||
|
62
pnpm-lock.yaml
generated
62
pnpm-lock.yaml
generated
@ -45,6 +45,7 @@ specifiers:
|
|||||||
vite-plugin-svg-icons: ^2.0.1
|
vite-plugin-svg-icons: ^2.0.1
|
||||||
vue: ^3.2.47
|
vue: ^3.2.47
|
||||||
vue-router: ^4.1.6
|
vue-router: ^4.1.6
|
||||||
|
xlsx: ^0.18.5
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vueuse/core': 9.13.0_vue@3.2.47
|
'@vueuse/core': 9.13.0_vue@3.2.47
|
||||||
@ -59,6 +60,7 @@ dependencies:
|
|||||||
vite: 4.2.1_sass@1.58.3
|
vite: 4.2.1_sass@1.58.3
|
||||||
vue: 3.2.47
|
vue: 3.2.47
|
||||||
vue-router: 4.1.6_vue@3.2.47
|
vue-router: 4.1.6_vue@3.2.47
|
||||||
|
xlsx: 0.18.5
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@commitlint/cli': 17.4.4
|
'@commitlint/cli': 17.4.4
|
||||||
@ -1406,6 +1408,11 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/adler-32/1.3.1:
|
||||||
|
resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/aggregate-error/3.1.0:
|
/aggregate-error/3.1.0:
|
||||||
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
|
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -1744,6 +1751,14 @@ packages:
|
|||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/cfb/1.2.2:
|
||||||
|
resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dependencies:
|
||||||
|
adler-32: 1.3.1
|
||||||
|
crc-32: 1.2.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/chalk/1.1.3:
|
/chalk/1.1.3:
|
||||||
resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
|
resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -1880,6 +1895,11 @@ packages:
|
|||||||
engines: {node: '>=0.8'}
|
engines: {node: '>=0.8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/codepage/1.15.0:
|
||||||
|
resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/collection-visit/1.0.0:
|
/collection-visit/1.0.0:
|
||||||
resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
|
resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -2078,6 +2098,12 @@ packages:
|
|||||||
path-type: 4.0.0
|
path-type: 4.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/crc-32/1.2.2:
|
||||||
|
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/create-require/1.1.1:
|
/create-require/1.1.1:
|
||||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -3001,6 +3027,11 @@ packages:
|
|||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/frac/1.1.2:
|
||||||
|
resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fragment-cache/0.2.1:
|
/fragment-cache/0.2.1:
|
||||||
resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
|
resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -5202,6 +5233,13 @@ packages:
|
|||||||
readable-stream: 3.6.0
|
readable-stream: 3.6.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/ssf/0.11.2:
|
||||||
|
resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dependencies:
|
||||||
|
frac: 1.1.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/ssr-window/3.0.0:
|
/ssr-window/3.0.0:
|
||||||
resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==}
|
resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -6130,11 +6168,21 @@ packages:
|
|||||||
resolution: {integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==}
|
resolution: {integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/wmf/1.0.2:
|
||||||
|
resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/word-wrap/1.2.3:
|
/word-wrap/1.2.3:
|
||||||
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
|
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/word/0.3.0:
|
||||||
|
resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/wrap-ansi/6.2.0:
|
/wrap-ansi/6.2.0:
|
||||||
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -6157,6 +6205,20 @@ packages:
|
|||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/xlsx/0.18.5:
|
||||||
|
resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
adler-32: 1.3.1
|
||||||
|
cfb: 1.2.2
|
||||||
|
codepage: 1.15.0
|
||||||
|
crc-32: 1.2.2
|
||||||
|
ssf: 0.11.2
|
||||||
|
wmf: 1.0.2
|
||||||
|
word: 0.3.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/y18n/5.0.8:
|
/y18n/5.0.8:
|
||||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { utils, writeFile } from 'xlsx'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
/**
|
/**
|
||||||
* @remote true: 后端分页 false: 前端分页
|
* @remote true: 后端分页 false: 前端分页
|
||||||
@ -73,7 +75,7 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:queryItems', 'onChecked'])
|
const emit = defineEmits(['update:queryItems', 'onChecked', 'onDataChange'])
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const initQuery = { ...props.queryItems }
|
const initQuery = { ...props.queryItems }
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
@ -94,6 +96,7 @@ async function handleQuery() {
|
|||||||
tableData.value = []
|
tableData.value = []
|
||||||
pagination.itemCount = 0
|
pagination.itemCount = 0
|
||||||
} finally {
|
} finally {
|
||||||
|
emit('onDataChange', tableData.value)
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,9 +125,21 @@ function onChecked(rowKeys) {
|
|||||||
emit('onChecked', rowKeys)
|
emit('onChecked', rowKeys)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function handleExport(columns = props.columns, data = tableData.value) {
|
||||||
|
if (!data?.length) return $message.warning('没有数据')
|
||||||
|
const columnsData = columns.filter((item) => !!item.title && !item.hideInExcel)
|
||||||
|
const thKeys = columnsData.map((item) => item.key)
|
||||||
|
const thData = columnsData.map((item) => item.title)
|
||||||
|
const trData = data.map((item) => thKeys.map((key) => item[key]))
|
||||||
|
const sheet = utils.aoa_to_sheet([thData, ...trData])
|
||||||
|
const workBook = utils.book_new()
|
||||||
|
utils.book_append_sheet(workBook, sheet, '数据报表')
|
||||||
|
writeFile(workBook, '数据报表.xlsx')
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
handleSearch,
|
handleSearch,
|
||||||
handleReset,
|
handleReset,
|
||||||
|
handleExport,
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<CommonPage show-footer title="文章">
|
<CommonPage show-footer title="文章">
|
||||||
<template #action>
|
<template #action>
|
||||||
<n-button type="primary" @click="handleAdd">
|
<div>
|
||||||
<TheIcon icon="material-symbols:add" :size="18" class="mr-5" /> 新建文章
|
<n-button type="primary" secondary @click="$table?.handleExport()">
|
||||||
</n-button>
|
<TheIcon icon="mdi:download" :size="18" class="mr-5" /> 导出
|
||||||
|
</n-button>
|
||||||
|
<n-button type="primary" class="ml-16" @click="handleAdd">
|
||||||
|
<TheIcon icon="material-symbols:add" :size="18" class="mr-5" /> 新建文章
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<CrudTable
|
<CrudTable
|
||||||
@ -14,6 +19,7 @@
|
|||||||
:columns="columns"
|
:columns="columns"
|
||||||
:get-data="api.getPosts"
|
:get-data="api.getPosts"
|
||||||
@on-checked="onChecked"
|
@on-checked="onChecked"
|
||||||
|
@on-data-change="(data) => (tableData = data)"
|
||||||
>
|
>
|
||||||
<template #queryBar>
|
<template #queryBar>
|
||||||
<QueryBarItem label="标题" :label-width="50">
|
<QueryBarItem label="标题" :label-width="50">
|
||||||
@ -89,6 +95,8 @@ import api from './api'
|
|||||||
defineOptions({ name: 'Crud' })
|
defineOptions({ name: 'Crud' })
|
||||||
|
|
||||||
const $table = ref(null)
|
const $table = ref(null)
|
||||||
|
/** 表格数据,触发搜索的时候会更新这个值 */
|
||||||
|
const tableData = ref([])
|
||||||
/** QueryBar筛选参数(可选) */
|
/** QueryBar筛选参数(可选) */
|
||||||
const queryItems = ref({})
|
const queryItems = ref({})
|
||||||
/** 补充参数(可选) */
|
/** 补充参数(可选) */
|
||||||
@ -141,6 +149,7 @@ const columns = [
|
|||||||
width: 240,
|
width: 240,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
|
hideInExcel: true,
|
||||||
render(row) {
|
render(row) {
|
||||||
return [
|
return [
|
||||||
h(
|
h(
|
||||||
|
Loading…
Reference in New Issue
Block a user