From eff76d8e599082df592c1588f3a7d28f8a9d9f2b Mon Sep 17 00:00:00 2001 From: syruan <15555146157@163.com> Date: Fri, 17 Oct 2025 18:14:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=87=BA=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + .../component/leaseCostRangeReportHome.vue | 310 ++++++++++-------- .../material/costPush/pushReview/index.vue | 174 +++++++++- 3 files changed, 337 insertions(+), 148 deletions(-) diff --git a/package.json b/package.json index 279cf74f..b5bd3a0d 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "crypto-js": "^4.2.0", "echarts": "5.4.0", "element-ui": "2.15.14", + "exceljs": "^4.4.0", "file-saver": "2.0.5", "fuse.js": "6.4.3", "highlight.js": "9.18.5", diff --git a/src/views/material/cost/component/leaseCostRangeReportHome.vue b/src/views/material/cost/component/leaseCostRangeReportHome.vue index 265f952f..c714dee9 100644 --- a/src/views/material/cost/component/leaseCostRangeReportHome.vue +++ b/src/views/material/cost/component/leaseCostRangeReportHome.vue @@ -212,7 +212,7 @@ import { import { getLeaseCostRangeReportList, getLeaseCostDetails } from '@/api/cost/cost' import Treeselect from "@riophae/vue-treeselect"; import "@riophae/vue-treeselect/dist/vue-treeselect.css"; -import * as XLSX from 'xlsx'; +import ExcelJS from 'exceljs'; export default { name: 'LeaseCostRangeReportHome', @@ -398,87 +398,103 @@ export default { }, // 导出Excel - exportExcel() { + async exportExcel() { if (!this.tableList || this.tableList.length === 0) { this.$modal.msgWarning('没有可导出的数据'); return; } try { - // 定义Excel列配置 + // 创建工作簿 + const workbook = new ExcelJS.Workbook(); + const worksheet = workbook.addWorksheet('租赁费用区间报表'); + + // 定义列配置 const columns = [ - { key: 'index', title: '序号' }, - { key: 'agreementCode', title: '协议号' }, - { key: 'unitName', title: '结算单位' }, - { key: 'projectName', title: '结算工程' }, - { key: 'isSettled', title: '结算状态' }, - { key: 'equipmentTypeCount', title: '设备类型数' }, - { key: 'totalEquipmentCount', title: '设备总数量' }, - { key: 'totalLeaseDays', title: '总租赁天数' }, - { key: 'totalLeaseCost', title: '总租赁费用(元)' }, - { key: 'avgDailyRent', title: '日均租金(元)' }, - { key: 'queryStartDate', title: '查询开始日期' }, - { key: 'queryEndDate', title: '查询结束日期' }, - { key: 'earliestLeaseTime', title: '最早租赁时间' }, - { key: 'latestReturnTime', title: '最晚归还时间' }, - { key: 'settlementTime', title: '结算时间' }, - { key: 'remark', title: '备注' } + { header: '序号', key: 'index', width: 8 }, + { header: '协议号', key: 'agreementCode', width: 18 }, + { header: '结算单位', key: 'unitName', width: 20 }, + { header: '结算工程', key: 'projectName', width: 25 }, + { header: '结算状态', key: 'isSettled', width: 10 }, + { header: '设备类型数', key: 'equipmentTypeCount', width: 12 }, + { header: '设备总数量', key: 'totalEquipmentCount', width: 12 }, + { header: '总租赁天数', key: 'totalLeaseDays', width: 12 }, + { header: '总租赁费用(元)', key: 'totalLeaseCost', width: 15 }, + { header: '日均租金(元)', key: 'avgDailyRent', width: 15 }, + { header: '查询开始日期', key: 'queryStartDate', width: 15 }, + { header: '查询结束日期', key: 'queryEndDate', width: 15 }, + { header: '最早租赁时间', key: 'earliestLeaseTime', width: 15 }, + { header: '最晚归还时间', key: 'latestReturnTime', width: 15 }, + { header: '结算时间', key: 'settlementTime', width: 12 }, + { header: '备注', key: 'remark', width: 20 } ]; - // 准备Excel数据 - const excelData = []; + worksheet.columns = columns; - // 添加表头 - const headerRow = columns.map(col => col.title); - excelData.push(headerRow); + // 定义表头样式 + const headerStyle = { + font: { bold: true, color: { argb: 'FFFFFFFF' }, size: 11 }, + fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF4472C4' } }, + alignment: { horizontal: 'center', vertical: 'center', wrapText: true }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 定义数据行样式 + const dataStyle = { + alignment: { horizontal: 'center', vertical: 'center' }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 设置表头样式 + worksheet.getRow(1).eachCell((cell) => { + cell.style = headerStyle; + }); // 添加数据行 this.tableList.forEach((row, index) => { - const dataRow = columns.map(col => { - if (col.key === 'index') { - return index + 1; - } else if (col.key === 'isSettled') { - return row.isSettled === '1' ? '已结算' : '未结算'; - } else if (col.key === 'totalEquipmentCount') { - return row.totalEquipmentCount ? parseFloat(row.totalEquipmentCount).toFixed(3) : '0.000'; - } else if (col.key === 'totalLeaseCost' || col.key === 'avgDailyRent') { - return row[col.key] ? parseFloat(row[col.key]).toFixed(2) : '0.00'; - } else { - return row[col.key] || ''; - } + const dataRow = { + index: index + 1, + agreementCode: row.agreementCode || '', + unitName: row.unitName || '', + projectName: row.projectName || '', + isSettled: row.isSettled === '1' ? '已结算' : '未结算', + equipmentTypeCount: row.equipmentTypeCount || '', + totalEquipmentCount: row.totalEquipmentCount ? parseFloat(row.totalEquipmentCount) : 0, + totalLeaseDays: row.totalLeaseDays || '', + totalLeaseCost: row.totalLeaseCost ? parseFloat(row.totalLeaseCost) : 0, + avgDailyRent: row.avgDailyRent ? parseFloat(row.avgDailyRent) : 0, + queryStartDate: row.queryStartDate || '', + queryEndDate: row.queryEndDate || '', + earliestLeaseTime: row.earliestLeaseTime || '', + latestReturnTime: row.latestReturnTime || '', + settlementTime: row.settlementTime || '', + remark: row.remark || '' + }; + + const newRow = worksheet.addRow(dataRow); + + // 设置数据行样式 + newRow.eachCell((cell) => { + cell.style = dataStyle; }); - excelData.push(dataRow); + + // 设置数字格式 + newRow.getCell(7).numFmt = '0.000'; // 设备总数量 + newRow.getCell(9).numFmt = '0.00'; // 总租赁费用 + newRow.getCell(10).numFmt = '0.00'; // 日均租金 }); - // 创建工作簿和工作表 - const workbook = XLSX.utils.book_new(); - const worksheet = XLSX.utils.aoa_to_sheet(excelData); - - // 设置列宽 - const columnWidths = [ - { wch: 8 }, // 序号 - { wch: 18 }, // 协议号啊 - { wch: 20 }, // 结算单位 - { wch: 25 }, // 结算工程 - { wch: 10 }, // 结算状态 - { wch: 12 }, // 设备类型数 - { wch: 12 }, // 设备总数量 - { wch: 12 }, // 总租赁天数 - { wch: 15 }, // 总租赁费用 - { wch: 15 }, // 日均租金 - { wch: 15 }, // 查询开始日期 - { wch: 15 }, // 查询结束日期 - { wch: 15 }, // 最早租赁时间 - { wch: 15 }, // 最晚归还时间 - { wch: 12 }, // 结算时间 - { wch: 20 } // 备注 - ]; - worksheet['!cols'] = columnWidths; - - // 添加工作表到工作簿 - XLSX.utils.book_append_sheet(workbook, worksheet, '租赁费用区间报表'); - - // 生成文件名(包含日期范围) + // 生成文件名 let fileName = '租赁费用区间报表'; if (this.queryParams.startDate && this.queryParams.endDate) { fileName += `_${this.queryParams.startDate}_至_${this.queryParams.endDate}`; @@ -486,8 +502,8 @@ export default { fileName += `_${new Date().toISOString().slice(0, 10)}.xlsx`; // 生成Excel文件并下载 - const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); - const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); + const buffer = await workbook.xlsx.writeBuffer(); + const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); // 创建下载链接 const link = document.createElement('a'); @@ -535,88 +551,104 @@ export default { }, /** 导出详情Excel */ - exportDetailExcel() { + async exportDetailExcel() { if (!this.detailTableList || this.detailTableList.length === 0) { this.$modal.msgWarning('没有可导出的详情数据'); return; } try { - // 定义详情Excel列配置 + // 创建工作簿 + const workbook = new ExcelJS.Workbook(); + const worksheet = workbook.addWorksheet('租赁费用明细'); + + // 定义列配置 const columns = [ - { key: 'index', title: '序号' }, - { key: 'agreementCode', title: '协议号' }, - { key: 'typeName', title: '机具名称' }, - { key: 'modelName', title: '机具规格' }, - { key: 'maCode', title: '物资编码' }, - { key: 'num', title: '租赁数量' }, - { key: 'mtUnitName', title: '单位' }, - { key: 'leasePrice', title: '租赁单价(元)' }, - { key: 'calcStartTime', title: '计算开始时间' }, - { key: 'calcEndTime', title: '计算结束时间' }, - { key: 'leaseDays', title: '租赁天数' }, - { key: 'leaseCost', title: '租赁费用(元)' }, - { key: 'isSettled', title: '结算状态' }, - { key: 'settlementTime', title: '结算时间' }, - { key: 'startTime', title: '出场时间' }, - { key: 'endTime', title: '退场时间' }, - { key: 'remark', title: '备注' } + { header: '序号', key: 'index', width: 8 }, + { header: '协议号', key: 'agreementCode', width: 18 }, + { header: '机具名称', key: 'typeName', width: 20 }, + { header: '机具规格', key: 'modelName', width: 15 }, + { header: '物资编码', key: 'maCode', width: 15 }, + { header: '租赁数量', key: 'num', width: 12 }, + { header: '单位', key: 'mtUnitName', width: 8 }, + { header: '租赁单价(元)', key: 'leasePrice', width: 18 }, + { header: '计算开始时间', key: 'calcStartTime', width: 15 }, + { header: '计算结束时间', key: 'calcEndTime', width: 15 }, + { header: '租赁天数', key: 'leaseDays', width: 10 }, + { header: '租赁费用(元)', key: 'leaseCost', width: 18 }, + { header: '结算状态', key: 'isSettled', width: 10 }, + { header: '结算时间', key: 'settlementTime', width: 15 }, + { header: '出场时间', key: 'startTime', width: 15 }, + { header: '退场时间', key: 'endTime', width: 15 }, + { header: '备注', key: 'remark', width: 20 } ]; - // 准备Excel数据 - const excelData = []; + worksheet.columns = columns; - // 添加表头 - const headerRow = columns.map(col => col.title); - excelData.push(headerRow); + // 定义表头样式 + const headerStyle = { + font: { bold: true, color: { argb: 'FFFFFFFF' }, size: 11 }, + fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF4472C4' } }, + alignment: { horizontal: 'center', vertical: 'center', wrapText: true }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 定义数据行样式 + const dataStyle = { + alignment: { horizontal: 'center', vertical: 'center' }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 设置表头样式 + worksheet.getRow(1).eachCell((cell) => { + cell.style = headerStyle; + }); // 添加数据行 this.detailTableList.forEach((row, index) => { - const dataRow = columns.map(col => { - if (col.key === 'index') { - return index + 1; - } else if (col.key === 'isSettled') { - return row.isSettled === '1' ? '已结算' : '未结算'; - } else if (col.key === 'num') { - return row.num ? parseFloat(row.num).toFixed(3) : '0.000'; - } else if (col.key === 'leasePrice' || col.key === 'leaseCost') { - return row[col.key] ? parseFloat(row[col.key]).toFixed(2) : '0.00'; - } else { - return row[col.key] || ''; - } + const dataRow = { + index: index + 1, + agreementCode: row.agreementCode || '', + typeName: row.typeName || '', + modelName: row.modelName || '', + maCode: row.maCode || '', + num: row.num ? parseFloat(row.num) : 0, + mtUnitName: row.mtUnitName || '', + leasePrice: row.leasePrice ? parseFloat(row.leasePrice) : 0, + calcStartTime: row.calcStartTime || '', + calcEndTime: row.calcEndTime || '', + leaseDays: row.leaseDays || '', + leaseCost: row.leaseCost ? parseFloat(row.leaseCost) : 0, + isSettled: row.isSettled === '1' ? '已结算' : '未结算', + settlementTime: row.settlementTime || '', + startTime: row.startTime || '', + endTime: row.endTime || '', + remark: row.remark || '' + }; + + const newRow = worksheet.addRow(dataRow); + + // 设置数据行样式 + newRow.eachCell((cell) => { + cell.style = dataStyle; }); - excelData.push(dataRow); + + // 设置数字格式 + newRow.getCell(6).numFmt = '0.000'; // 租赁数量 + newRow.getCell(8).numFmt = '0.00'; // 租赁单价 + newRow.getCell(12).numFmt = '0.00'; // 租赁费用 }); - // 创建工作簿和工作表 - const workbook = XLSX.utils.book_new(); - const worksheet = XLSX.utils.aoa_to_sheet(excelData); - - // 设置列宽 - const columnWidths = [ - { wch: 8 }, // 序号 - { wch: 18 }, // 协议号 - { wch: 20 }, // 机具名称 - { wch: 15 }, // 机具规格 - { wch: 15 }, // 物资编码 - { wch: 12 }, // 租赁数量 - { wch: 8 }, // 单位 - { wch: 15 }, // 租赁单价 - { wch: 15 }, // 计算开始时间 - { wch: 15 }, // 计算结束时间 - { wch: 10 }, // 租赁天数 - { wch: 15 }, // 租赁费用 - { wch: 10 }, // 结算状态 - { wch: 15 }, // 结算时间 - { wch: 15 }, // 出场时间 - { wch: 15 }, // 退场时间 - { wch: 20 } // 备注 - ]; - worksheet['!cols'] = columnWidths; - - // 添加工作表到工作簿 - XLSX.utils.book_append_sheet(workbook, worksheet, '租赁费用明细'); - // 生成文件名 let fileName = `租赁费用明细_${this.selectedRowData.agreementCode}`; if (this.detailQueryParams.startDate && this.detailQueryParams.endDate) { @@ -625,8 +657,8 @@ export default { fileName += `_${new Date().toISOString().slice(0, 10)}.xlsx`; // 生成Excel文件并下载 - const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); - const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); + const buffer = await workbook.xlsx.writeBuffer(); + const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); // 创建下载链接 const link = document.createElement('a'); @@ -662,15 +694,15 @@ export default { padding: 15px; border-radius: 4px; margin-bottom: 15px; - + .detail-info { margin-bottom: 10px; - + .label { font-weight: bold; color: #606266; } - + .value { color: #303133; margin-left: 5px; diff --git a/src/views/material/costPush/pushReview/index.vue b/src/views/material/costPush/pushReview/index.vue index 5116d133..fa71ccd6 100644 --- a/src/views/material/costPush/pushReview/index.vue +++ b/src/views/material/costPush/pushReview/index.vue @@ -437,6 +437,7 @@ import { import {getPushReviewList,getLeaseListApi,getRepairList,getLoseList,getScrapList,submitPushCosts } from "@/api/costPush/costPush"; import Treeselect from "@riophae/vue-treeselect"; import "@riophae/vue-treeselect/dist/vue-treeselect.css"; +import ExcelJS from 'exceljs'; export default { name: "PushReview", data() { @@ -512,7 +513,7 @@ export default { modelName: undefined, }, dialogRepairTotal: 0, - repairAllMoney: 0, + repairAllMoney: 0, currentRepairRow: null, // 当前维修费用行数据 //报废费用弹窗 @@ -931,14 +932,169 @@ export default { // ) }, /** 外层导出 */ - handleExport() { - this.download( - 'material/iws_cost_push/exportCostPushExamList', - { - ...this.queryParams, - }, - `费用推送审核记录_${new Date().getTime()}.xlsx`, - ) + async handleExport() { + if (!this.pushReviewList || this.pushReviewList.length === 0) { + this.$modal.msgWarning('没有可导出的数据'); + return; + } + + try { + // 创建工作簿 + const workbook = new ExcelJS.Workbook(); + const worksheet = workbook.addWorksheet('费用推送审核记录'); + + // 定义列配置 + const columns = [ + { header: '序号', key: 'index', width: 8 }, + { header: '协议号', key: 'agreementCode', width: 18 }, + { header: '单位名称', key: 'unitName', width: 20 }, + { header: '工程名称', key: 'projectName', width: 20 }, + { header: '推送月份', key: 'month', width: 12 }, + { header: '费用所属', key: 'settlementType', width: 12 }, + { header: '租赁费用(元)', key: 'leaseMoney', width: 18 }, + { header: '维修费用(元)', key: 'repairMoney', width: 18 }, + { header: '报废费用(元)', key: 'scrapMoney', width: 18 }, + { header: '丢失费用(元)', key: 'lostMoney', width: 18 }, + { header: '合计费用(元)', key: 'money', width: 18 }, + { header: '是否结算', key: 'isSettlement', width: 12 }, + { header: '是否审核', key: 'checkStatus', width: 12 } + ]; + + worksheet.columns = columns; + + // 定义表头样式 + const headerStyle = { + font: { bold: true, color: { argb: 'FFFFFFFF' }, size: 11 }, + fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF4472C4' } }, + alignment: { horizontal: 'center', vertical: 'center', wrapText: true }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 定义数据行样式 + const dataStyle = { + alignment: { horizontal: 'center', vertical: 'center' }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 定义合计行样式 + const totalStyle = { + font: { bold: true, size: 11 }, + fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFF8F8F9' } }, + alignment: { horizontal: 'center', vertical: 'center' }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 设置表头样式 + worksheet.getRow(1).eachCell((cell) => { + cell.style = headerStyle; + }); + + // 添加数据行(排除最后一行合计行) + const dataRows = this.pushReviewList.slice(0, -1); + dataRows.forEach((row, index) => { + const dataRow = { + index: index + 1, + agreementCode: row.agreementCode || '', + unitName: row.unitName || '', + projectName: row.projectName || '', + month: this.originalMonthTrue || row.month || '', + settlementType: row.settlementType === 1 ? '工器具' : (row.settlementType === 2 ? '安全用品' : ''), + leaseMoney: row.leaseMoney ? parseFloat(row.leaseMoney) : 0, + repairMoney: row.repairMoney ? parseFloat(row.repairMoney) : 0, + scrapMoney: row.scrapMoney ? parseFloat(row.scrapMoney) : 0, + lostMoney: row.lostMoney ? parseFloat(row.lostMoney) : 0, + money: row.money ? parseFloat(row.money) : 0, + isSettlement: row.isSettlement === 1 || row.isSettlement === 2 ? '已结算' : '未结算', + checkStatus: row.checkStatus === 1 ? '已审核' : '未审核' + }; + + const newRow = worksheet.addRow(dataRow); + + // 设置数据行样式 + newRow.eachCell((cell) => { + cell.style = dataStyle; + }); + + // 设置费用列的数字格式(2位小数) + newRow.getCell(7).numFmt = '0.00'; // 租赁费用 + newRow.getCell(8).numFmt = '0.00'; // 维修费用 + newRow.getCell(9).numFmt = '0.00'; // 报废费用 + newRow.getCell(10).numFmt = '0.00'; // 丢失费用 + newRow.getCell(11).numFmt = '0.00'; // 合计费用 + }); + + // 添加合计行 + const totalRow = this.pushReviewList[this.pushReviewList.length - 1]; + const totalDataRow = { + index: '合计', + agreementCode: '', + unitName: '', + projectName: '', + month: '', + settlementType: '', + leaseMoney: totalRow.leaseMoney ? parseFloat(totalRow.leaseMoney) : 0, + repairMoney: totalRow.repairMoney ? parseFloat(totalRow.repairMoney) : 0, + scrapMoney: totalRow.scrapMoney ? parseFloat(totalRow.scrapMoney) : 0, + lostMoney: totalRow.lostMoney ? parseFloat(totalRow.lostMoney) : 0, + money: totalRow.money ? parseFloat(totalRow.money) : 0, + isSettlement: '', + checkStatus: '' + }; + + const newTotalRow = worksheet.addRow(totalDataRow); + + // 设置合计行样式 + newTotalRow.eachCell((cell) => { + cell.style = totalStyle; + }); + + // 设置合计行费用列的数字格式 + newTotalRow.getCell(7).numFmt = '0.00'; // 租赁费用 + newTotalRow.getCell(8).numFmt = '0.00'; // 维修费用 + newTotalRow.getCell(9).numFmt = '0.00'; // 报废费用 + newTotalRow.getCell(10).numFmt = '0.00'; // 丢失费用 + newTotalRow.getCell(11).numFmt = '0.00'; // 合计费用 + + // 生成文件名 + const fileName = `费用推送审核记录_${new Date().toISOString().slice(0, 10)}.xlsx`; + + // 生成Excel文件并下载 + const buffer = await workbook.xlsx.writeBuffer(); + const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); + + // 创建下载链接 + const link = document.createElement('a'); + const url = URL.createObjectURL(blob); + link.setAttribute('href', url); + link.setAttribute('download', fileName); + link.style.visibility = 'hidden'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // 清理URL对象 + URL.revokeObjectURL(url); + + this.$modal.msgSuccess('Excel导出成功'); + } catch (error) { + console.error('导出Excel失败:', error); + this.$modal.msgError('导出Excel失败,请稍后重试'); + } }, /** 提交 */