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

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);
    }
  }
相关推荐
liangshanbo121518 小时前
写好 React useEffect 的终极指南
前端·javascript·react.js
哆啦A梦158820 小时前
搜索页面布局
前端·vue.js·node.js
_院长大人_21 小时前
el-table-column show-overflow-tooltip 只能显示纯文本,无法渲染 <p> 标签
前端·javascript·vue.js
哆啦A梦15881 天前
axios 的二次封装
前端·vue.js·node.js
阿珊和她的猫1 天前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
yinuo1 天前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端
snow@li1 天前
html5:拖放 / demo / 拖放事件(Drag Events)/ DataTransfer 对象方法
前端·html·拖放
浪裡遊1 天前
Nivo图表库全面指南:配置与用法详解
前端·javascript·react.js·node.js·php
漂流瓶jz1 天前
快速定位源码问题:SourceMap的生成/使用/文件格式与历史
前端·javascript·前端工程化
samroom1 天前
iframe实战:跨域通信与安全隔离
前端·安全