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

news2025/6/12 21:59:26
// 导出
  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);
    }
  }

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2407783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…