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

javascript 复制代码
// 导出
  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);
    }
  }
相关推荐
Fluxart.ai14 分钟前
商品多角度图怎么做?Flux Art 从白底图到规格图、包装图的 10 步教程
开发语言·前端·javascript
前端繁华如梦25 分钟前
React + Three.js 造了一个"乙烯基娃娃"3D 角色编辑器:配方驱动、程序化生成、还能跳舞
前端
繁华若梦75926 分钟前
全项目 Skills 适配:把「会写代码的 Agent」变成「会按你们规范干活的同事」
前端
江华森40 分钟前
云原生从0到1:Kubernetes 工作负载实战——Deployment/Service/滚动更新/弹性伸缩
前端·后端
江华森1 小时前
《云原生从0到1:4台华为云ECS搭建Kubernetes 1.28集群实录(上)——环境与踩坑全记录》
前端·后端
codeY1 小时前
Vite 前端发布后「点击菜单没反应」?旧版本资源 404 的完整排查与修复实录
前端·前端工程化
90后的晨仔1 小时前
uni-app Vue3 状态管理 Pinia 完全指南:从概念到实战的深度解析
前端
mqiqe1 小时前
AgentScope Java 2.0 集成 Chat Completions Web:一行依赖让你的 Agent 变身 OpenAI 兼容服务
java·开发语言·前端
程序员小八7771 小时前
后端开发初学TypeScript
前端·javascript·typescript