WXL (wul)
5 天以前 ba1ad6cff887cecb836a9fff87d84c146c820ad7
src/views/sfstatistics/percentage/index.vue
@@ -1700,40 +1700,68 @@
    // 替换您原来的 exportTable 方法
    async exportTable() {
      try {
        // 获取当前日期
        const now = new Date();
        // 获取当前月份(注意月份从0开始,需要加1)
        const currentMonth = now.getMonth() + 1;
        // 构建文件名
        const excelName = `${currentMonth}月出院随访统计表.xlsx`;
        // 1. 获取并格式化日期范围
        let dateRangeString = ""; // 用于文件名
        let sheetNameSuffix = ""; // 用于工作表名
        // 检查是否存在选中的日期范围
        if (
          this.queryParams.dateRange &&
          this.queryParams.dateRange.length === 2
        ) {
          const startDateStr = this.queryParams.dateRange[0]; // 开始日期字符串,例如 "2026-01-01 00:00:00"
          const endDateStr = this.queryParams.dateRange[1]; // 结束日期字符串
          // 格式化日期为 YYYY-MM-DD(去掉时间部分)
          const formatDateForDisplay = (dateTimeStr) => {
            return dateTimeStr.split(" ")[0]; // 取空格前的部分,即 "YYYY-MM-DD"
          };
          const startDateFormatted = formatDateForDisplay(startDateStr);
          const endDateFormatted = formatDateForDisplay(endDateStr);
          // 构建日期范围字符串
          dateRangeString = `${startDateFormatted}至${endDateFormatted}`;
          sheetNameSuffix = `${startDateFormatted}至${endDateFormatted}`;
        } else {
          // 如果没有选择日期范围,则使用当前月份作为备选方案
          const now = new Date();
          const currentMonth = now.getMonth() + 1;
          dateRangeString = `${currentMonth}月`;
          sheetNameSuffix = `${currentMonth}月`;
        }
        // 2. 动态构建文件名和工作表名
        const excelName = `出院随访统计表_${dateRangeString}.xlsx`;
        const worksheetName = `随访统计_${sheetNameSuffix}`; // 工作表名不能超过31个字符[2](@ref)
        // 创建新的工作簿和工作表
        const workbook = new ExcelJS.Workbook();
        const worksheet = workbook.addWorksheet(`${currentMonth}月出院随访统计表`);
// 定义样式(新增总标题样式)
    const titleStyle = {
      font: {
        name: "微软雅黑",
        size: 16,
        bold: true,
        color: { argb: "FF000000" },
      },
      fill: {
        type: "pattern",
        pattern: "solid",
        fgColor: { argb: "FFE6F3FF" },
      },
      alignment: {
        vertical: "middle",
        horizontal: "center",
        wrapText: true,
      },
      border: {
        top: { style: "thin", color: { argb: "FFD0D0D0" } },
        left: { style: "thin", color: { argb: "FFD0D0D0" } },
        bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
        right: { style: "thin", color: { argb: "FFD0D0D0" } },
      },
    };
        const worksheet = workbook.addWorksheet(worksheetName); // 使用动态工作表名
        // 定义样式(新增总标题样式)
        const titleStyle = {
          font: {
            name: "微软雅黑",
            size: 16,
            bold: true,
            color: { argb: "FF000000" },
          },
          fill: {
            type: "pattern",
            pattern: "solid",
            fgColor: { argb: "FFE6F3FF" },
          },
          alignment: {
            vertical: "middle",
            horizontal: "center",
            wrapText: true,
          },
          border: {
            top: { style: "thin", color: { argb: "FFD0D0D0" } },
            left: { style: "thin", color: { argb: "FFD0D0D0" } },
            bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
            right: { style: "thin", color: { argb: "FFD0D0D0" } },
          },
        };
        // 定义样式
        const headerStyle = {
          font: {
@@ -1801,12 +1829,12 @@
            right: { style: "thin", color: { argb: "FFD0D0D0" } },
          },
        };
// 1. 添加总标题行(第一行)
    worksheet.mergeCells(1, 1, 1, 23); // 合并A1到W1的所有列[1,4](@ref)
    const titleCell = worksheet.getCell(1, 1);
    titleCell.value = `${currentMonth}月出院随访统计表`; // 使用文件名作为总标题
    titleCell.style = titleStyle;
    worksheet.getRow(1).height = 35; // 设置总标题行高
        // 1. 添加总标题行(第一行)
        worksheet.mergeCells(1, 1, 1, 23); // 合并A1到W1的所有列[1,4](@ref)
        const titleCell = worksheet.getCell(1, 1);
        titleCell.value = `${sheetNameSuffix}出院随访统计表`; // 使用文件名作为总标题
        titleCell.style = titleStyle;
        worksheet.getRow(1).height = 35; // 设置总标题行高
        // 1. 首先,创建并设置第二行(子表头)的所有单元格
        const secondRowHeaders = [
          "", // A2 展开列占位(其值将由第一行合并后的主单元格决定)
@@ -1837,95 +1865,98 @@
        ];
        // 添加第二行(原第一行下移)
    secondRowHeaders.forEach((header, index) => {
      const cell = worksheet.getCell(3, index + 1); // 改为第3行
      cell.value = header;
      cell.style = headerStyle;
    });
        secondRowHeaders.forEach((header, index) => {
          const cell = worksheet.getCell(3, index + 1); // 改为第3行
          cell.value = header;
          cell.style = headerStyle;
        });
    // 3. 调整原合并单元格位置(原第1行合并单元格下移到第2行)
    // 合并 A2:A3
    worksheet.mergeCells(2, 1, 3, 1);
    worksheet.getCell(2, 1).value = "";
    worksheet.getCell(2, 1).style = headerStyle;
        // 3. 调整原合并单元格位置(原第1行合并单元格下移到第2行)
        // 合并 A2:A3
        worksheet.mergeCells(2, 1, 3, 1);
        worksheet.getCell(2, 1).value = "";
        worksheet.getCell(2, 1).style = headerStyle;
    // 合并 B2:B3
    worksheet.mergeCells(2, 2, 3, 2);
    worksheet.getCell(2, 2).value = "出院病区";
    worksheet.getCell(2, 2).style = headerStyle;
        // 合并 B2:B3
        worksheet.mergeCells(2, 2, 3, 2);
        worksheet.getCell(2, 2).value = "出院病区";
        worksheet.getCell(2, 2).style = headerStyle;
    // 合并 C2:C3
    worksheet.mergeCells(2, 3, 3, 3);
    worksheet.getCell(2, 3).value = "科室";
    worksheet.getCell(2, 3).style = headerStyle;
        // 合并 C2:C3
        worksheet.mergeCells(2, 3, 3, 3);
        worksheet.getCell(2, 3).value = "科室";
        worksheet.getCell(2, 3).style = headerStyle;
    // 合并 D2:D3
    worksheet.mergeCells(2, 4, 3, 4);
    worksheet.getCell(2, 4).value = "出院人次";
    worksheet.getCell(2, 4).style = headerStyle;
        // 合并 D2:D3
        worksheet.mergeCells(2, 4, 3, 4);
        worksheet.getCell(2, 4).value = "出院人次";
        worksheet.getCell(2, 4).style = headerStyle;
    // 合并 E2:E3
    worksheet.mergeCells(2, 5, 3, 5);
    worksheet.getCell(2, 5).value = "无需随访人次";
    worksheet.getCell(2, 5).style = headerStyle;
        // 合并 E2:E3
        worksheet.mergeCells(2, 5, 3, 5);
        worksheet.getCell(2, 5).value = "无需随访人次";
        worksheet.getCell(2, 5).style = headerStyle;
    // 合并 F2:F3
    worksheet.mergeCells(2, 6, 3, 6);
    worksheet.getCell(2, 6).value = "应随访人次";
    worksheet.getCell(2, 6).style = headerStyle;
        // 合并 F2:F3
        worksheet.mergeCells(2, 6, 3, 6);
        worksheet.getCell(2, 6).value = "应随访人次";
        worksheet.getCell(2, 6).style = headerStyle;
    // 4. 调整横向合并标题位置(下移到第2行)
    // 首次出院随访(合并G2:O2)
    worksheet.mergeCells(2, 7, 2, 15); // G2:O2
    worksheet.getCell(2, 7).value = "首次出院随访";
    worksheet.getCell(2, 7).style = headerStyle;
        // 4. 调整横向合并标题位置(下移到第2行)
        // 首次出院随访(合并G2:O2)
        worksheet.mergeCells(2, 7, 2, 15); // G2:O2
        worksheet.getCell(2, 7).value = "首次出院随访";
        worksheet.getCell(2, 7).style = headerStyle;
    // 再次出院随访(合并P2:W2)
    worksheet.mergeCells(2, 16, 2, 23); // P2:W2
    worksheet.getCell(2, 16).value = "再次出院随访";
    worksheet.getCell(2, 16).style = headerStyle;
        // 再次出院随访(合并P2:W2)
        worksheet.mergeCells(2, 16, 2, 23); // P2:W2
        worksheet.getCell(2, 16).value = "再次出院随访";
        worksheet.getCell(2, 16).style = headerStyle;
    // 5. 设置行高
    worksheet.getRow(1).height = 35; // 总标题行高
    worksheet.getRow(2).height = 28; // 原第一行下移
    worksheet.getRow(3).height = 25; // 原第二行下移
        // 5. 设置行高
        worksheet.getRow(1).height = 35; // 总标题行高
        worksheet.getRow(2).height = 28; // 原第一行下移
        worksheet.getRow(3).height = 25; // 原第二行下移
    // 6. 添加数据行(注意行索引需要+1,因为上面插入了一行)
    this.userList.forEach((item, rowIndex) => {
      const dataRow = worksheet.addRow([
        "", // 展开列
        item.leavehospitaldistrictname || "",
        item.deptname || "",
        item.dischargeCount || 0,
        item.nonFollowUp || 0,
        item.followUpNeeded || 0,
        // 首次出院随访数据
        item.needFollowUp || 0,
        item.pendingFollowUp || 0,
        item.followUpSuccess || 0,
        item.followUpFail || 0,
        item.followUpRate || "0%",
        item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%",
        item.manual || 0,
        item.sms || 0,
        item.weChat || 0,
        // 再次出院随访数据
        item.needFollowUpAgain || 0,
        item.pendingFollowUpAgain || 0,
        item.followUpSuccessAgain || 0,
        item.followUpFailAgain || 0,
        item.followUpRateAgain || "0%",
        item.manualAgain || 0,
        item.smsAgain || 0,
        item.weChatAgain || 0,
      ], rowIndex + 4); // 从第4行开始添加数据(原第3行)
        // 6. 添加数据行(注意行索引需要+1,因为上面插入了一行)
        this.userList.forEach((item, rowIndex) => {
          const dataRow = worksheet.addRow(
            [
              "", // 展开列
              item.leavehospitaldistrictname || "",
              item.deptname || "",
              item.dischargeCount || 0,
              item.nonFollowUp || 0,
              item.followUpNeeded || 0,
              // 首次出院随访数据
              item.needFollowUp || 0,
              item.pendingFollowUp || 0,
              item.followUpSuccess || 0,
              item.followUpFail || 0,
              item.followUpRate || "0%",
              item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%",
              item.manual || 0,
              item.sms || 0,
              item.weChat || 0,
              // 再次出院随访数据
              item.needFollowUpAgain || 0,
              item.pendingFollowUpAgain || 0,
              item.followUpSuccessAgain || 0,
              item.followUpFailAgain || 0,
              item.followUpRateAgain || "0%",
              item.manualAgain || 0,
              item.smsAgain || 0,
              item.weChatAgain || 0,
            ],
            rowIndex + 4
          ); // 从第4行开始添加数据(原第3行)
      // 应用数据行样式
      dataRow.eachCell((cell) => {
        cell.style = cellStyle;
      });
      dataRow.height = 24;
    });
          // 应用数据行样式
          dataRow.eachCell((cell) => {
            cell.style = cellStyle;
          });
          dataRow.height = 24;
        });
        // 添加合计行
        const summaries = this.getSummaries({