2
0

增加导出插件

This commit is contained in:
lai
2024-12-26 16:05:34 +08:00
parent 1000f591ef
commit 8ac4d3f9df
3 changed files with 179 additions and 1 deletions

View File

@@ -24,16 +24,19 @@
"clipboard": "2.0.11",
"dayjs": "1.11.11",
"echarts": "5.5.0",
"file-saver": "^2.0.5",
"lodash-es": "4.17.21",
"nprogress": "0.2.0",
"pinia": "2.1.7",
"vue": "3.4.27",
"vue-draggable-plus": "0.5.0",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2"
"vue-router": "4.3.2",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@elegant-router/vue": "0.3.7",
"@types/file-saver": "^2.0.7",
"@iconify/json": "2.2.217",
"@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.3.6",

88
pnpm-lock.yaml generated
View File

@@ -44,6 +44,9 @@ importers:
echarts:
specifier: 5.5.0
version: 5.5.0
file-saver:
specifier: ^2.0.5
version: 2.0.5
lodash-es:
specifier: 4.17.21
version: 4.17.21
@@ -65,6 +68,9 @@ importers:
vue-router:
specifier: 4.3.2
version: 4.3.2(vue@3.4.27(typescript@5.4.5))
xlsx:
specifier: ^0.18.5
version: 0.18.5
devDependencies:
'@elegant-router/vue':
specifier: 0.3.7
@@ -78,6 +84,9 @@ importers:
'@soybeanjs/eslint-config':
specifier: 1.3.6
version: 1.3.6(@types/eslint@8.56.10)(@unocss/eslint-config@0.60.4(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-vue@9.26.0(eslint@9.4.0))(eslint@9.4.0)(typescript@5.4.5)(vue-eslint-parser@9.4.3(eslint@9.4.0))
'@types/file-saver':
specifier: ^2.0.7
version: 2.0.7
'@types/lodash-es':
specifier: 4.17.12
version: 4.17.12
@@ -913,6 +922,9 @@ packages:
'@types/estree@1.0.5':
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
'@types/file-saver@2.0.7':
resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==}
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
@@ -1254,6 +1266,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==}
@@ -1465,6 +1481,10 @@ packages:
caniuse-lite@1.0.30001629:
resolution: {integrity: sha512-c3dl911slnQhmxUIT4HhYzT7wnBK/XYpGnYLOj4nJBaRiw52Ibe7YxlDaAeRECvA786zCuExhxIUJ2K7nHMrBw==}
cfb@1.2.2:
resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==}
engines: {node: '>=0.8'}
chai@4.4.1:
resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==}
engines: {node: '>=4'}
@@ -1526,6 +1546,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'}
@@ -1604,6 +1628,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.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@@ -2124,6 +2153,9 @@ packages:
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
engines: {node: '>=16.0.0'}
file-saver@2.0.5:
resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==}
fill-range@4.0.0:
resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==}
engines: {node: '>=0.10.0'}
@@ -2175,6 +2207,10 @@ packages:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
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'}
@@ -3536,6 +3572,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@0.1.8:
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
@@ -4063,10 +4103,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'}
@@ -4082,6 +4130,11 @@ packages:
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
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'}
@@ -4737,6 +4790,8 @@ snapshots:
'@types/estree@1.0.5': {}
'@types/file-saver@2.0.7': {}
'@types/json-schema@7.0.15': {}
'@types/json5@0.0.29': {}
@@ -5233,6 +5288,8 @@ snapshots:
acorn@8.11.3: {}
adler-32@1.3.1: {}
ajv@6.12.6:
dependencies:
fast-deep-equal: 3.1.3
@@ -5481,6 +5538,11 @@ snapshots:
caniuse-lite@1.0.30001629: {}
cfb@1.2.2:
dependencies:
adler-32: 1.3.1
crc-32: 1.2.2
chai@4.4.1:
dependencies:
assertion-error: 1.1.0
@@ -5566,6 +5628,8 @@ snapshots:
clone@2.1.2: {}
codepage@1.15.0: {}
collection-visit@1.0.0:
dependencies:
map-visit: 1.0.0
@@ -5626,6 +5690,8 @@ snapshots:
object-assign: 4.1.1
vary: 1.1.2
crc-32@1.2.2: {}
cross-spawn@7.0.3:
dependencies:
path-key: 3.1.1
@@ -6373,6 +6439,8 @@ snapshots:
dependencies:
flat-cache: 4.0.1
file-saver@2.0.5: {}
fill-range@4.0.0:
dependencies:
extend-shallow: 2.0.1
@@ -6426,6 +6494,8 @@ snapshots:
combined-stream: 1.0.8
mime-types: 2.1.35
frac@1.1.2: {}
fragment-cache@0.2.1:
dependencies:
map-cache: 0.2.2
@@ -7842,6 +7912,10 @@ snapshots:
dependencies:
extend-shallow: 3.0.2
ssf@0.11.2:
dependencies:
frac: 1.1.2
stable@0.1.8: {}
stackback@0.0.2: {}
@@ -8448,8 +8522,12 @@ snapshots:
siginfo: 2.0.0
stackback: 0.0.2
wmf@1.0.2: {}
word-wrap@1.2.5: {}
word@0.3.0: {}
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
@@ -8470,6 +8548,16 @@ snapshots:
wrappy@1.0.2: {}
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: {}

87
src/utils/execl-utils.ts Normal file
View File

@@ -0,0 +1,87 @@
import { JSON2SheetOpts, read, utils, write } from 'xlsx';
// 静态资源路径
const baseUrl = import.meta.env.VITE_HISTORY_BASE_URL;
export const xlsxUrl = `${
baseUrl.length === 1 && baseUrl.indexOf('/') === 0
? ''
: baseUrl.indexOf('/') === -1
? '/' + baseUrl
: baseUrl
}/alarmHelp`;
/**
* 读取本地文件
* @param id 表格ID
* @returns 数据数组
* @example
* readLoalXlsx('20001').then(res=>{
* console.log(res)
* });
*/
export async function readLoalXlsx(
lang: string,
id: string
): Promise<Record<string, any>[]> {
let result = await fetch(`${xlsxUrl}/${lang}/${id}.xlsx`);
let fileBuffer = await result.arrayBuffer();
// 判断是否xlsx文件
const data = new Uint8Array(fileBuffer);
const isXlsxFile =
data[0] === 0x50 &&
data[1] === 0x4b &&
data[2] === 0x03 &&
data[3] === 0x04;
if (!isXlsxFile) {
result = await fetch(`${xlsxUrl}/${lang}/all.xlsx`);
fileBuffer = await result.arrayBuffer();
}
return readSheet(fileBuffer, 0);
}
/**
* 读取表格数据 工作表
* @param fileBolb 文件对象
* @param index 文件保存路径
* @return 表格对象列表
*/
export async function readSheet(
fileBolb: Blob | ArrayBuffer,
index: number = 0
): Promise<Record<string, string>[]> {
const workBook = read(fileBolb);
let workSheet = workBook.Sheets[workBook.SheetNames[index]];
return utils.sheet_to_json<Record<string, string>>(workSheet);
}
/**
* 写入表格数据,一般用于导出
* @param filePath 文件路径
* @param sheetName 工作表名称
* @return xlsx文件流 使用saveAs函数保存
* @example
* writeSheet(res.data, from.logType).then(fileBlob =>
* saveAs(fileBlob, `${from.logType}_${Date.now()}.xlsx`)
* );
*
*/
export async function writeSheet(
data: any[],
sheetName: string,
opts?: JSON2SheetOpts
) {
if (data.length === 0) {
return new Blob([], { type: 'application/octet-stream' });
}
const workSheet = utils.json_to_sheet(data, opts);
// 设置列宽度,单位厘米
workSheet['!cols'] = Object.keys(data[0]).map(() => {
return { wch: 20 };
});
const workBook = utils.book_new();
utils.book_append_sheet(workBook, workSheet, sheetName);
const excelBuffer = write(workBook, { type: 'array', bookType: 'xlsx' });
return new Blob([excelBuffer], { type: 'application/octet-stream' });
}