|
|
@@ -29,7 +29,7 @@
|
|
|
</div>
|
|
|
<div class="content_right">
|
|
|
<el-button class="delete_button_border_no_bg" @click="ClearTeachingRelationship">清空授课</el-button>
|
|
|
- <el-button class="button_refresh">批量导出</el-button>
|
|
|
+ <el-button class="button_refresh" @click="HandleExportExcel">批量导出</el-button>
|
|
|
<el-button class="button_refresh">批量导入</el-button>
|
|
|
<el-button class="button_background" @click="FinishTeachingRelationship">完成</el-button>
|
|
|
</div>
|
|
|
@@ -142,9 +142,12 @@
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { ref, reactive, onMounted } from 'vue';
|
|
|
-import { useRoute } from 'vue-router';
|
|
|
+import { ErrorTypes, useRoute } from 'vue-router';
|
|
|
import { useStore } from 'vuex';
|
|
|
|
|
|
+import ExcelJS from 'exceljs';
|
|
|
+
|
|
|
+
|
|
|
import { Close } from '@element-plus/icons-vue';
|
|
|
import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
|
|
|
import Table from '@/baseComponents/Table.vue';
|
|
|
@@ -516,6 +519,175 @@ const ClearTeachingRelationship = async ()=>{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// 批量导入/导出
|
|
|
+
|
|
|
+//前端 导出 Excel
|
|
|
+const LoopAddSheet=(finalTableColumn, finalTableData,workbook,sheetName )=>{
|
|
|
+ // 1. 提取表头
|
|
|
+ // 行政班和教学班不一样
|
|
|
+ let headers = [] // 行政班表头数据
|
|
|
+ let topHeaders:any[] = [] // 教学班 表头数据
|
|
|
+ let bottomHeaders:any[] = [] // 教学班 子表头数据
|
|
|
+
|
|
|
+ // 2.创建工作表
|
|
|
+ const worksheet = workbook.addWorksheet(sheetName);
|
|
|
+
|
|
|
+ // 3. 添加表头行
|
|
|
+ let headerRow
|
|
|
+ let subHeaderRow
|
|
|
+
|
|
|
+ if(sheetName == '行政班'){
|
|
|
+ headers = finalTableColumn.map(column => column.label || column.name)
|
|
|
+ // 行政班:普通表头
|
|
|
+ headerRow = worksheet.addRow(headers)
|
|
|
+ // 定义表头样式
|
|
|
+ headerRow.eachCell((cell) => {
|
|
|
+ cell.style = {
|
|
|
+ font: { name: 'Microsoft YaHei', size: 12, bold: true, color: { argb: 'FF333333' } },
|
|
|
+ fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFF4F6F8' } },
|
|
|
+ border: {
|
|
|
+ top: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ left: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ bottom: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ right: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ },
|
|
|
+ alignment: { vertical: 'middle', horizontal: 'left', wrapText: true },
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ }else if(sheetName == '教学班'){
|
|
|
+ finalTableColumn.forEach(column => {
|
|
|
+ topHeaders.push(column.label || column.name)
|
|
|
+ topHeaders.push('') // 占位,用于合并
|
|
|
+ bottomHeaders.push('班级')
|
|
|
+ bottomHeaders.push('教师')
|
|
|
+ })
|
|
|
+
|
|
|
+ // 添加第一层表头
|
|
|
+ headerRow = worksheet.addRow(topHeaders)
|
|
|
+ // 添加第二层表头
|
|
|
+ subHeaderRow = worksheet.addRow(bottomHeaders)
|
|
|
+
|
|
|
+ // 定义第一层表头样式
|
|
|
+ headerRow.eachCell((cell) => {
|
|
|
+ cell.style = {
|
|
|
+ font: { name: 'Microsoft YaHei', size: 12, bold: true, color: { argb: 'FF333333' } },
|
|
|
+ fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFF4F6F8' } },
|
|
|
+ border: {
|
|
|
+ top: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ left: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ bottom: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ right: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ },
|
|
|
+ alignment: { vertical: 'middle', horizontal: 'center', wrapText: true },
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 定义第二层表头样式
|
|
|
+ subHeaderRow.eachCell((cell) => {
|
|
|
+ cell.style = {
|
|
|
+ font: { name: 'Microsoft YaHei', size: 11, bold: true, color: { argb: 'FF333333' } },
|
|
|
+ fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFF9FAFB' } },
|
|
|
+ border: {
|
|
|
+ top: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ left: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ bottom: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ right: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ },
|
|
|
+ alignment: { vertical: 'middle', horizontal: 'center', wrapText: true },
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 添加数据行
|
|
|
+ // 行政班 和 教学班 不一样
|
|
|
+ finalTableData.forEach(row => {
|
|
|
+ const rowData = finalTableColumn.map(column => {
|
|
|
+ if (column.name === 'className') {
|
|
|
+ return row?.className?.className || '';
|
|
|
+ }
|
|
|
+ const cellValue = row[column.name];
|
|
|
+ if(sheetName == '行政班'){
|
|
|
+ return cellValue?.map((item: any) => item.teacherName || '').join(',') || '-';
|
|
|
+ }else if(sheetName == '教学班'){
|
|
|
+ let className = cellValue.className.className
|
|
|
+ let teacherList = cellValue.teacherList
|
|
|
+ let teacherName = teacherList.map((item: any) => item.teacherName || '').join(',') || '-';
|
|
|
+ return [className,teacherName]
|
|
|
+ }
|
|
|
+ }).flat();
|
|
|
+
|
|
|
+ const excelRow = worksheet.addRow(rowData);
|
|
|
+
|
|
|
+ // 6. 定义数据行样式
|
|
|
+ excelRow.eachCell({ includeEmpty: true }, (cell) => {
|
|
|
+ cell.style = {
|
|
|
+ font: { name: 'Microsoft YaHei', size: 12, color: { argb: 'FF333333' } },
|
|
|
+ border: {
|
|
|
+ top: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ left: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ bottom: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ right: { style: 'thin', color: { argb: 'FFD9D9D9' } },
|
|
|
+ },
|
|
|
+ alignment: { vertical: 'top', horizontal: 'left', wrapText: true },
|
|
|
+ };
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 5. 设置列宽
|
|
|
+ if(sheetName == '行政班'){
|
|
|
+ worksheet.columns = headers.map(() => ({ width: 25 }));
|
|
|
+ }else if(sheetName == '教学班'){
|
|
|
+ worksheet.columns = bottomHeaders.map(() => ({ width: 25 }));
|
|
|
+ //放到最后合并 合并第一层表头的两列,放到设置列表前面,合并头的 宽度会缩小
|
|
|
+ let colIndex = 1
|
|
|
+ finalTableColumn.forEach(() => {
|
|
|
+ worksheet.mergeCells(1, colIndex, 1, colIndex + 1)
|
|
|
+ colIndex += 2
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const HandleExportExcel = async () => {
|
|
|
+ // 1. 初始化sheet列表
|
|
|
+ let sheetList = [
|
|
|
+ {
|
|
|
+ tableColumn:filterAdministrativeClassTableColumns.value,
|
|
|
+ tableData:administrativeClassTableData.value,
|
|
|
+ sheetName:'行政班'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ tableColumn:filterTeachingClassTableColumns.value,
|
|
|
+ tableData:teachingClassTableData.value,
|
|
|
+ sheetName:'教学班'
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ // 2. 创建工作簿
|
|
|
+ const workbook = new ExcelJS.Workbook();
|
|
|
+
|
|
|
+ // 3. 添加sheet表
|
|
|
+ sheetList.forEach(item=>{
|
|
|
+ LoopAddSheet(item.tableColumn,item.tableData,workbook,item.sheetName)
|
|
|
+ })
|
|
|
+
|
|
|
+ // 4. 导出文件
|
|
|
+ const buffer = await workbook.xlsx.writeBuffer();
|
|
|
+ const blob = new Blob([buffer], {
|
|
|
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
|
+ });
|
|
|
+
|
|
|
+ const url = URL.createObjectURL(blob);
|
|
|
+ const link = document.createElement('a');
|
|
|
+ link.href = url;
|
|
|
+ link.download = `授课关系表_${new Date().toISOString().slice(0, 10)}.xlsx`;
|
|
|
+ link.style.visibility = 'hidden';
|
|
|
+ document.body.appendChild(link);
|
|
|
+ link.click();
|
|
|
+ document.body.removeChild(link);
|
|
|
+ URL.revokeObjectURL(url);
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
// 重新加载页面数据
|
|
|
const reloadData =async ()=>{
|
|
|
await GetTeacherTableData()
|