feat: 使用web worker来进行文件导入计算

This commit is contained in:
LOG1997
2025-09-21 22:35:28 +08:00
parent 88e773da37
commit 7ea677f029
3 changed files with 64 additions and 14 deletions

View File

@@ -1,16 +1,17 @@
<!-- eslint-disable vue/no-parsing-error --> <!-- eslint-disable vue/no-parsing-error -->
<script setup lang='ts'> <script setup lang='ts'>
import type { IPersonConfig } from '@/types/storeType' import type { IPersonConfig } from '@/types/storeType'
import DaiysuiTable from '@/components/DaiysuiTable/index.vue'
import i18n from '@/locales/i18n'
import useStore from '@/store'
import { addOtherInfo } from '@/utils'
import { readFileBinary } from '@/utils/file'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import * as XLSX from 'xlsx' import * as XLSX from 'xlsx'
import DaiysuiTable from '@/components/DaiysuiTable/index.vue'
import i18n from '@/locales/i18n'
import useStore from '@/store'
import { readFileBinary } from '@/utils/file'
import ImportExcelWorker from './importExcel.worker?worker'
const worker: Worker | null = new ImportExcelWorker()
const { t } = useI18n() const { t } = useI18n()
const personConfig = useStore().personConfig const personConfig = useStore().personConfig
const { getAllPersonList: allPersonList, getAlreadyPersonList: alreadyPersonList } = storeToRefs(personConfig) const { getAllPersonList: allPersonList, getAlreadyPersonList: alreadyPersonList } = storeToRefs(personConfig)
@@ -19,15 +20,27 @@ const limitType = '.xlsx,.xls'
const resetDataDialog = ref() const resetDataDialog = ref()
const delAllDataDialog = ref() const delAllDataDialog = ref()
function sendMessage(message: any) {
if (worker) {
worker.postMessage(message)
}
}
// 方法
function startWorker(data: Event) {
sendMessage({ type: 'start', data })
}
async function handleFileChange(e: Event) { async function handleFileChange(e: Event) {
const dataBinary = await readFileBinary(((e.target as HTMLInputElement).files as FileList)[0]!) // worker = new ImportExcelWorker()
const workBook = XLSX.read(dataBinary, { type: 'binary', cellDates: true }) if (worker) {
const workSheet = workBook.Sheets[workBook.SheetNames[0]] worker.onmessage = (e) => {
const excelData = XLSX.utils.sheet_to_json(workSheet) if (e.data.type === 'done') {
const allData = addOtherInfo(excelData)
personConfig.resetPerson() personConfig.resetPerson()
personConfig.addNotPersonList(allData) personConfig.addNotPersonList(e.data.data)
}
}
}
const dataBinary = await readFileBinary(((e.target as HTMLInputElement).files as FileList)[0]!)
startWorker(dataBinary)
} }
function exportData() { function exportData() {
let data = JSON.parse(JSON.stringify(allPersonList.value)) let data = JSON.parse(JSON.stringify(allPersonList.value))
@@ -99,8 +112,8 @@ const tableColumns = [
label: i18n.global.t('data.avatar'), label: i18n.global.t('data.avatar'),
props: 'avatar', props: 'avatar',
formatValue(row: any) { formatValue(row: any) {
return row.avatar ? `<img src="${row.avatar}" alt="avatar" style="width: 50px; height: 50px;"/>` : '-'; return row.avatar ? `<img src="${row.avatar}" alt="avatar" style="width: 50px; height: 50px;"/>` : '-'
} },
}, },
{ {
label: i18n.global.t('data.identity'), label: i18n.global.t('data.identity'),

View File

@@ -0,0 +1,32 @@
import * as XLSX from 'xlsx'
import { addOtherInfo } from '@/utils'
// 定义消息类型
interface WorkerMessage {
type: 'start' | 'stop' | 'reset'
data: any
}
let allData: any[] = []
// 接收主线程消息
globalThis.onmessage = async (e: MessageEvent<WorkerMessage>) => {
switch (e.data.type) {
case 'start':
{
const fileData = e.data.data
// const dataBinary = await readFileBinary(((fileEvent.target as HTMLInputElement).files as FileList)[0]!)
const workBook = XLSX.read(fileData, { type: 'binary', cellDates: true })
const workSheet = workBook.Sheets[workBook.SheetNames[0]]
const excelData = XLSX.utils.sheet_to_json(workSheet)
allData = addOtherInfo(excelData)
globalThis.postMessage({
type: 'done',
data: allData,
message: '读取完成',
})
break
}
default:
break
}
}

View File

@@ -1,4 +1,9 @@
<script setup lang='ts'> <script setup lang='ts'>
import { onMounted, ref, watch } from 'vue'
onMounted(() => {
})
</script> </script>
<template> <template>