前端导出带有合并单元格的列表

发布于:2025-06-12 ⋅ 阅读:(19) ⋅ 点赞:(0)
// 导出
  async function exportExcel(fileName = "共识调整.xlsx") {
    // 所有数据
    const exportData = await getAllMainData();
    // 表头内容
    let fitstTitleList = [];
    const secondTitleList = [];
    allColumns.value.forEach(column => {
      if (!column.children) {
        fitstTitleList.push(column.label);
        secondTitleList.push("");
      } else {
        const arr = [column.label, "", ""];
        fitstTitleList = fitstTitleList.concat(arr);
        column.children.forEach(child => {
          secondTitleList.push(child.label);
        });
      }
    });
    let res = exportData.map(item => {
      // 固定列数据
      const fixedData = [item.dimension, item.sku, item.skuDescr1];
      const dynamicData =
        item.qtyData?.flatMap(qtyItem => {
          const arr = [
            qtyItem.machPreQty || "",
            qtyItem.sumQty || "",
            qtyItem.adjRate || ""
          ];
          return arr;
        }) || [];
      return [...fixedData, ...dynamicData];
    });
    res = [fitstTitleList, secondTitleList, ...res];
    const workSheet = utils.aoa_to_sheet(res);
    // 合并单元格
    setMergedCells(workSheet, res);
    // 设置样式
    setStyleCells(utils, workSheet);
    // 设置列宽
    workSheet["!cols"] = [
      { wch: 15 }, // 预测维度
      { wch: 15 }, // 产品代码
      { wch: 20 }, // 产品描述
      ...Array(fitstTitleList.length - 3).fill({ wch: 12 }) // 动态列宽
    ];
    const workBook = utils.book_new();
    utils.book_append_sheet(workBook, workSheet, "数据报表");
    writeFile(workBook, fileName);
    message("导出成功", { type: "success" });
  }
  // 设置样式
  function setStyleCells(utils, workSheet) {
	  // 获取表格范围
	  const range = utils.decode_range(workSheet["!ref"] || "A1:A1");
	  const dataStyle = {
	    alignment: { horizontal: "center", vertical: "center" },
	    border: {
	      top: { style: "thin" },
	      bottom: { style: "thin" },
	      left: { style: "thin" },
	      right: { style: "thin" }
	    }
	  };
	  // 遍历所有单元格,设置水平和垂直居中对齐
	  for (let r = range.s.r; r <= range.e.r; r++) {
	    for (let c = range.s.c; c <= range.e.c; c++) {
	      const cellAddress = utils.encode_cell({ r, c });
	      const cell = workSheet[cellAddress];
	      if (cell) {
	        // 创建或更新样式对象
	        cell.s = { ...(cell.s || {}), ...dataStyle };
	      }
	    }
	  }
	}
  // 设置合并单元格
  function setMergedCells(workSheet, res) {
    const mergeRanges = [];
    const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
    const firstRow = res[0];
    // 处理日期列
    for (let colIndex = 0; colIndex < firstRow.length; colIndex++) {
      const cellValue = firstRow[colIndex];
      if (cellValue && dateRegex.test(String(cellValue))) {
        // 创建合并范围
        const mergeRange = {
          s: { r: 0, c: colIndex },
          e: { r: 0, c: colIndex + 2 }
        };
        mergeRanges.push(mergeRange);
        colIndex += 2; // 跳过已处理的列
      }
    }
    // 处理左侧固定列
    const fixedColumns = [
      { s: { r: 0, c: 0 }, e: { r: 1, c: 0 } }, // 预测维度
      { s: { r: 0, c: 1 }, e: { r: 1, c: 1 } }, // 产品代码
      { s: { r: 0, c: 2 }, e: { r: 1, c: 2 } } // 产品描述
    ];
    fixedColumns.forEach(range => {
      mergeRanges.push(range);
    });
    // 应用合并范围到工作表
    workSheet["!merges"] = mergeRanges;
  }
  // 获取所有数据
  async function getAllMainData() {
    try {
      if (pagination.total === dataList.value.length) {
        return dataList.value;
      } else {
        const params = {
          ...form,
          pageSize: pagination.total,
          currentPage: 1
        };
        const { data } = await getConsensusList(toRaw(params));
        return data?.list ?? [];
      }
    } finally {
      setTimeout(() => {
        loading.value = false;
      }, 500);
    }
  }

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到