Browse Source

批量导入学生

我还能继续跑 8 months ago
parent
commit
8e71f8b912
2 changed files with 133 additions and 1 deletions
  1. 132 0
      src/views/work/work/components/participantForm.vue
  2. 1 1
      src/views/work/work/workForm.vue

+ 132 - 0
src/views/work/work/components/participantForm.vue

@@ -54,6 +54,27 @@
   </el-form>
   <el-row justify="center" class="mt-3">
     <el-button :disabled="props.dis"  @click="handleAdd" round>+ 添加参演人员</el-button>
+    <el-upload
+      :on-change="handleUpload"
+      accept="xlsx"
+      ref="keyupload"
+      class="upload-demo"
+      :action="actionUrl"
+      :on-preview="handlePreview"
+      :on-remove="handleRemove"
+      :headers="{ Authorization: token }"
+      :before-remove="beforeRemove"
+      :on-success="uploadSuccess"
+      :limit="1"
+      :before-upload="beforeColorUpload1"
+      :show-file-list="false"
+      :file-list="fileList2"
+      :disabled="value2==''"
+      style="margin-left: 10px"
+    >
+      <el-button type="warning"><Icon icon="ep:upload" /> 批量导入参演人员</el-button>
+    </el-upload>
+    <el-button type="success" @click="downloadTemplate" style="margin-left: 10px"><Icon icon="ep:download" /> 下载导入模板</el-button>
   </el-row>
 </template>
 <script setup lang="ts">
@@ -68,6 +89,117 @@ const formData = ref([])
 const formRules = reactive({
 })
 const formRef = ref() // 表单 Ref
+//绘制导入模板
+import * as XLSX from 'xlsx';
+
+const writeFileAsync = (workbook, filename, options) => {
+  return new Promise((resolve, reject) => {
+    try {
+      XLSX.writeFile(workbook, filename, options);
+      resolve();
+    } catch (error) {
+      reject(error);
+    }
+  });
+};
+
+const downloadTemplate = async () => {
+  // 构造json
+  const json = [
+    {
+      姓名: '张三',
+      性别: '男',
+      班级: '7年级2班',
+      学籍号: '24371598456',
+      年龄: '12'
+    }
+  ]
+  // 将json数据转换成excel文件
+  const worksheet = XLSX.utils.json_to_sheet(json);
+  const workbook = XLSX.utils.book_new();
+  XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
+
+  try {
+    // 将excel 文件保存为blob
+    const blob = await writeFileAsync(workbook, '人员导入模板.xlsx', { bookType: 'xlsx', mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+
+    if (blob instanceof Blob) {
+      // 创建下载链接
+      const url = window.URL.createObjectURL(blob);
+
+      // 创建隐藏的a标签,设置下载链接并触发点击
+      const a = document.createElement('a');
+      a.href = url;
+      a.download = 'excel.template.xlsx';
+      document.body.appendChild(a);
+      a.click();
+      // 释放对象url
+      window.URL.revokeObjectURL(url);
+      // 等待5秒后关闭模态框
+      setTimeout(() => {
+        document.body.removeChild(a);
+      }, 5000);
+    } else {
+      throw new Error('Invalid Blob');
+    }
+  } catch (error) {
+    //console.error('Error creating object URL:', error);
+  }
+};
+//读取文件
+//读取excel文件
+const readFile = (file) => {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader()
+    reader.readAsArrayBuffer(file.raw)
+    reader.onload = (e) => {
+      resolve(e.target.result)
+    }
+    reader.onerror = (e) => {
+      reject(e)
+    }
+  })
+}
+
+const handleUpload = async (file) => {
+  const data = await getXlsxData(file)
+  console.log(data)
+  formData.value = translateField(data)
+  console.log("-----------------")
+  console.log(formData.value)
+}
+
+//读取表格数据
+const getXlsxData = async (file) => {
+  const dataBinary = await readFile(file)
+  const workBook = XLSX.read(dataBinary)
+  const workSheet = workBook.Sheets[workBook.SheetNames[0]]
+  const data = XLSX.utils.sheet_to_json(workSheet)
+  // const newData = data.slice(0, data.length - 1)
+  return data
+}
+
+//映射字段
+const translateField = (data) => {
+  const arr = []
+  const cnToEn = {
+    姓名: 'name',
+    性别: 'gender',
+    班级: 'className',
+    学籍号: 'studentId',
+    年龄: 'age'
+  }
+  data.forEach((item) => {
+    const arrItem = {}
+    Object.keys(item).forEach((key) => {
+      arrItem[cnToEn[key]] = item[key]
+    })
+    arr.push(arrItem)
+  })
+  return arr
+}
+
+
 
 /** 监听主表的关联字段的变化,加载对应的子表数据 */
 watch(

+ 1 - 1
src/views/work/work/workForm.vue

@@ -81,7 +81,7 @@
           :limit="1"
           multiple
           drag
-          :accept="'.pdf'"
+          :accept="'.pdf,.doc,.docx'"
         >
           <i class="el-icon-upload"></i>
           <div class="el-upload__text" style="width: 300px">