mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-23 23:39:47 +08:00
Compare commits
3 Commits
flow-v1.1.
...
7f2f3bd088
Author | SHA1 | Date | |
---|---|---|---|
7f2f3bd088 | |||
5ef1c5de98 | |||
90a14e338a |
@ -84,7 +84,8 @@
|
||||
"vue-advanced-cropper": "^2.8.9",
|
||||
"vue-draggable-plus": "0.6.0",
|
||||
"vue-i18n": "11.1.9",
|
||||
"vue-router": "4.5.1"
|
||||
"vue-router": "4.5.1",
|
||||
"xlsx": "0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@elegant-router/vue": "0.3.8",
|
||||
|
72
pnpm-lock.yaml
generated
72
pnpm-lock.yaml
generated
@ -92,6 +92,9 @@ importers:
|
||||
vue-router:
|
||||
specifier: 4.5.1
|
||||
version: 4.5.1(vue@3.5.17(typescript@5.8.3))
|
||||
xlsx:
|
||||
specifier: 0.18.5
|
||||
version: 0.18.5
|
||||
devDependencies:
|
||||
'@elegant-router/vue':
|
||||
specifier: 0.3.8
|
||||
@ -1547,6 +1550,10 @@ packages:
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
adler-32@1.3.1:
|
||||
resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
|
||||
@ -1752,6 +1759,10 @@ packages:
|
||||
caniuse-lite@1.0.30001727:
|
||||
resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==}
|
||||
|
||||
cfb@1.2.2:
|
||||
resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
chalk@1.1.3:
|
||||
resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -1801,6 +1812,10 @@ packages:
|
||||
resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
codepage@1.15.0:
|
||||
resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
collection-visit@1.0.0:
|
||||
resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -1871,6 +1886,11 @@ packages:
|
||||
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
crc-32@1.2.2:
|
||||
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
|
||||
engines: {node: '>=0.8'}
|
||||
hasBin: true
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
@ -2393,6 +2413,10 @@ packages:
|
||||
resolution: {integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
frac@1.1.2:
|
||||
resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
fragment-cache@0.2.1:
|
||||
resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -3652,6 +3676,10 @@ packages:
|
||||
resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
ssf@0.11.2:
|
||||
resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
stable-hash-x@0.2.0:
|
||||
resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@ -4168,10 +4196,18 @@ packages:
|
||||
engines: {node: '>= 8'}
|
||||
hasBin: true
|
||||
|
||||
wmf@1.0.2:
|
||||
resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
word-wrap@1.2.5:
|
||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
word@0.3.0:
|
||||
resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
@ -4184,6 +4220,11 @@ packages:
|
||||
resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
xlsx@0.18.5:
|
||||
resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==}
|
||||
engines: {node: '>=0.8'}
|
||||
hasBin: true
|
||||
|
||||
xml-name-validator@4.0.0:
|
||||
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
||||
engines: {node: '>=12'}
|
||||
@ -5465,6 +5506,8 @@ snapshots:
|
||||
|
||||
acorn@8.15.0: {}
|
||||
|
||||
adler-32@1.3.1: {}
|
||||
|
||||
ajv@6.12.6:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
@ -5691,6 +5734,11 @@ snapshots:
|
||||
|
||||
caniuse-lite@1.0.30001727: {}
|
||||
|
||||
cfb@1.2.2:
|
||||
dependencies:
|
||||
adler-32: 1.3.1
|
||||
crc-32: 1.2.2
|
||||
|
||||
chalk@1.1.3:
|
||||
dependencies:
|
||||
ansi-styles: 2.2.1
|
||||
@ -5757,6 +5805,8 @@ snapshots:
|
||||
|
||||
clone@2.1.2: {}
|
||||
|
||||
codepage@1.15.0: {}
|
||||
|
||||
collection-visit@1.0.0:
|
||||
dependencies:
|
||||
map-visit: 1.0.0
|
||||
@ -5811,6 +5861,8 @@ snapshots:
|
||||
object-assign: 4.1.1
|
||||
vary: 1.1.2
|
||||
|
||||
crc-32@1.2.2: {}
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
@ -6469,6 +6521,8 @@ snapshots:
|
||||
hasown: 2.0.2
|
||||
mime-types: 2.1.35
|
||||
|
||||
frac@1.1.2: {}
|
||||
|
||||
fragment-cache@0.2.1:
|
||||
dependencies:
|
||||
map-cache: 0.2.2
|
||||
@ -7742,6 +7796,10 @@ snapshots:
|
||||
dependencies:
|
||||
extend-shallow: 3.0.2
|
||||
|
||||
ssf@0.11.2:
|
||||
dependencies:
|
||||
frac: 1.1.2
|
||||
|
||||
stable-hash-x@0.2.0: {}
|
||||
|
||||
stable@0.1.8: {}
|
||||
@ -8363,8 +8421,12 @@ snapshots:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
wmf@1.0.2: {}
|
||||
|
||||
word-wrap@1.2.5: {}
|
||||
|
||||
word@0.3.0: {}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
@ -8381,6 +8443,16 @@ snapshots:
|
||||
dependencies:
|
||||
is-wsl: 3.1.0
|
||||
|
||||
xlsx@0.18.5:
|
||||
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
|
||||
|
||||
xml-name-validator@4.0.0: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, useAttrs } from 'vue';
|
||||
import type { TagProps } from 'naive-ui';
|
||||
import { jsonClone } from '@sa/utils';
|
||||
import { useDict } from '@/hooks/business/dict';
|
||||
import { isNotNull } from '@/utils/common';
|
||||
import { $t } from '@/locales';
|
||||
@ -28,7 +29,7 @@ const { transformDictData } = useDict(props.dictCode, props.immediate);
|
||||
|
||||
const dictTagData = computed<Api.System.DictData[]>(() => {
|
||||
if (props.dictData) {
|
||||
const dictData = props.dictData;
|
||||
const dictData = jsonClone(props.dictData);
|
||||
if (dictData.dictLabel?.startsWith(`dict.${dictData.dictType}.`)) {
|
||||
dictData.dictLabel = $t(dictData.dictLabel as App.I18n.I18nKey);
|
||||
}
|
||||
|
@ -113,6 +113,10 @@ export function useDownload() {
|
||||
|
||||
const response = await fetch(fullUrl, requestOptions);
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error(errorCodeRecord.default);
|
||||
}
|
||||
|
||||
await handleResponse(response);
|
||||
|
||||
const rawHeader = response.headers.get('Download-Filename');
|
||||
|
71
src/utils/export.ts
Normal file
71
src/utils/export.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import { utils, writeFile } from 'xlsx';
|
||||
import { isNotNull } from '@/utils/common';
|
||||
import { $t } from '@/locales';
|
||||
|
||||
export interface ExportExcelProps<T> {
|
||||
columns: NaiveUI.TableColumn<NaiveUI.TableDataWithIndex<T>>[];
|
||||
data: NaiveUI.TableDataWithIndex<T>[];
|
||||
filename: string;
|
||||
ignoreKeys?: (keyof NaiveUI.TableDataWithIndex<T> | NaiveUI.CustomColumnKey)[];
|
||||
dicts?: Record<keyof NaiveUI.TableDataWithIndex<T>, string>;
|
||||
}
|
||||
|
||||
export function exportExcel<T>({
|
||||
columns,
|
||||
data,
|
||||
filename,
|
||||
dicts,
|
||||
ignoreKeys = ['index', 'operate']
|
||||
}: ExportExcelProps<T>) {
|
||||
const exportColumns = columns.filter(col => isTableColumnHasKey(col) && !ignoreKeys?.includes(col.key));
|
||||
|
||||
const excelList = data.map(item => exportColumns.map(col => getTableValue(col, item, dicts)));
|
||||
|
||||
const titleList = exportColumns.map(col => (isTableColumnHasTitle(col) && col.title) || null);
|
||||
|
||||
excelList.unshift(titleList);
|
||||
|
||||
const workBook = utils.book_new();
|
||||
|
||||
const workSheet = utils.aoa_to_sheet(excelList);
|
||||
|
||||
workSheet['!cols'] = exportColumns.map(item => ({
|
||||
width: Math.round(Number(item.width) / 10 || 20)
|
||||
}));
|
||||
|
||||
utils.book_append_sheet(workBook, workSheet, filename);
|
||||
|
||||
writeFile(workBook, `${filename}.xlsx`);
|
||||
}
|
||||
|
||||
function getTableValue<T>(
|
||||
col: NaiveUI.TableColumn<NaiveUI.TableDataWithIndex<T>>,
|
||||
item: NaiveUI.TableDataWithIndex<T>,
|
||||
dicts?: Record<keyof NaiveUI.TableDataWithIndex<T>, string>
|
||||
) {
|
||||
if (!isTableColumnHasKey(col)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { key } = col;
|
||||
|
||||
if (key === 'operate') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isNotNull(dicts?.[key]) && isNotNull(item[key])) {
|
||||
return $t(item[key] as App.I18n.I18nKey);
|
||||
}
|
||||
|
||||
return item[key];
|
||||
}
|
||||
|
||||
function isTableColumnHasKey<T>(column: NaiveUI.TableColumn<T>): column is NaiveUI.TableColumnWithKey<T> {
|
||||
return Boolean((column as NaiveUI.TableColumnWithKey<T>).key);
|
||||
}
|
||||
|
||||
function isTableColumnHasTitle<T>(column: NaiveUI.TableColumn<T>): column is NaiveUI.TableColumnWithKey<T> & {
|
||||
title: string;
|
||||
} {
|
||||
return Boolean((column as NaiveUI.TableColumnWithKey<T>).title);
|
||||
}
|
Reference in New Issue
Block a user