Explorar el Código

添加评价码 和评价账号配置的Excel导出

lm hace 1 mes
padre
commit
877da2eedc

+ 109 - 3
src/views/reviewManagement/stepComponent/reviewAccountComponent/GenerateReviewCode.vue

@@ -7,7 +7,7 @@
                 </div>
                 <div class="content_right">
                     <el-button class="button_refresh">导出PDF</el-button>
-                    <el-button class="button_refresh">导出Excel</el-button>
+                    <el-button class="button_refresh"  @click="HandleExportExcel">导出Excel</el-button>
                     <el-button :class="[store.state.evaluationManageStepData.isAllowDeleteOrEdit ?  'button_border' : 'is-disabled']" 
                         @click="store.state.evaluationManageStepData.isAllowDeleteOrEdit ?  GoToReviewAccountConfig() : ''">重新生成</el-button>
                     <el-button :class="[store.state.evaluationManageStepData.isAllowDeleteOrEdit ? 'button_background' : 'is-disabled']" 
@@ -42,9 +42,10 @@
 <script setup lang="ts">
 import { ref,watch } from 'vue';
 import { useStore } from 'vuex';
-
 import { useRoute,useRouter } from 'vue-router';
 
+import ExcelJS from 'exceljs';
+
 import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
 import Table from '@/baseComponents/Table.vue';
 
@@ -218,7 +219,7 @@ const HandleSelectSearchChange = async (params,key)=>{
 
 
 
-// 3. 完成评价账号
+// 4. 完成评价账号
 const FinishReviewAccount = async()=>{
     let res = await finishReviewAccountApi(route.query.id)
     if(res?.code == 200){
@@ -229,6 +230,111 @@ const FinishReviewAccount = async()=>{
     }
 }
 
+
+// 导出 Excel
+const HandleExportExcel = async () => {
+    // 1. 初始化sheet列表
+    let finalTableColumn = generateCodeTableColumns.value.slice(1)
+    let finalTableData = tableData.value
+    let sheetName = '评价码'
+
+    // 2. 创建工作簿 和 工作表
+    const workbook = new ExcelJS.Workbook();
+    const worksheet = workbook.addWorksheet(sheetName);
+
+    // 3. 添加表头行
+    let headers = finalTableColumn.map(column => column.label || column.name)
+    let headerRow = worksheet.addRow(headers)
+    //4. 定义表头样式
+    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 },
+        }
+    })
+
+    // 5. 添加数据行和二维码图片
+    for (let i = 0; i < finalTableData.length; i++) {
+        const row = finalTableData[i];
+        const rowData = finalTableColumn.map(column => {
+            const cellValue = row[column.name];
+            return cellValue || '-'
+        })
+        const excelRow = worksheet.addRow(rowData);
+        
+        // 设置行高以适应二维码
+        excelRow.height = 100;
+        
+        // 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: 'middle', horizontal: 'left', wrapText: true },
+            };
+        });
+        
+        // 插入二维码图片
+        const qrCodeColumnIndex = finalTableColumn.findIndex(column => column.name === 'requestUrl');
+        if (qrCodeColumnIndex !== -1 && row.qrCode) {
+            // 移除 DataURL 的前缀(如 data:image/png;base64,)
+            const base64Data = row.qrCode.split(',')[1];
+            const imageId = workbook.addImage({
+                base64: base64Data,
+                extension: 'png',
+            });
+            
+            // 计算图片位置,在 requestUrl 列旁边插入图片
+            const colLetter = worksheet.getColumn(qrCodeColumnIndex + 1).letter;
+            const rowNum = i + 2; // i 从 0 开始,第 1 行是表头
+            
+            // 添加图片,设置图片的位置和大小
+            worksheet.addImage(imageId, {
+                tl: { col: qrCodeColumnIndex + 1, row: rowNum - 1 },
+                ext: { width: 80, height: 80 },
+            });
+        }
+    };
+
+    // 5. 设置列宽
+    worksheet.columns = finalTableColumn.map((column, index) => {
+        if (column.name === 'requestUrl') {
+            return { width: 35 };
+        }
+        return { width: 25 };
+    });
+
+    // 6. 导出文件
+    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);
+};
+
+
+
 // 根据是否按照性别生成评价码 控制 表格项和搜索项的显隐
 watch(()=>store.state.evaluationManageStepData.isGenerateAccountByGender,(newVal)=>{
     generateCodeTableColumns.value = generateCodeTableColumns.value.map(item=>{

+ 79 - 1
src/views/reviewManagement/stepComponent/reviewAccountComponent/ReviewAccountComponent.vue

@@ -11,7 +11,7 @@
                 <div class="content_right">
                     <el-button  class="delete_button_border_no_bg" @click="ClearReviewAccount">全部清空</el-button>
                     <el-button  class="button_border" @click="OpenBatchEditForm">批量编辑</el-button>
-                    <el-button  class="button_refresh" @click="">批量导出</el-button>
+                    <el-button  class="button_refresh" @click="HandleExportExcel">批量导出</el-button>
                     <el-button  class="button_refresh" @click="">批量导入</el-button>
                     <el-button  class="button_background" @click="GoToGenerateCodePage">生成评价码</el-button>
                 </div>
@@ -98,6 +98,8 @@ import { onMounted,ref,watch } from 'vue';
 import { useStore } from 'vuex';
 import { useRoute,useRouter } from 'vue-router';
 
+import ExcelJS from 'exceljs';
+
 import Table from '@/baseComponents/Table.vue';
 import FormDialog from '@/baseComponents/FormDialog.vue';
 
@@ -414,6 +416,82 @@ const GoToGenerateCodePage = ()=>{
     router.push(`generateReviewCode?id=${route.query.id}`)
 }
 
+// 5. 批量导入/ 导出
+const HandleExportExcel = async () => {
+    // 1. 初始化sheet列表
+    let finalTableColumn = tableColumns.value
+    let finalTableData = tableData.value
+    let sheetName = '评价账号'
+
+    // 2. 创建工作簿 和 工作表
+    const workbook = new ExcelJS.Workbook();
+    const worksheet = workbook.addWorksheet(sheetName);
+
+    // 3. 添加表头行
+    let headers = finalTableColumn.map(column => column.label || column.name)
+    let headerRow = worksheet.addRow(headers)
+    //4. 定义表头样式
+    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 },
+        }
+    })
+
+    // 5. 添加数据行
+    finalTableData.forEach(row => {
+        const rowData = finalTableColumn.map(column => {
+            const cellValue = row[column.name];
+            if(column.name.startsWith('class_')){
+                return cellValue?.className
+            }
+            return cellValue || '-'
+        })
+        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. 设置列宽
+    worksheet.columns = headers.map(() => ({ width: 25 }));
+
+
+
+    // 6. 导出文件
+    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);
+};
+
 
 onMounted(async ()=>{
     let reviewAccountMsg = sessionStorage.getItem('reviewAccountMsg')