vue + ant-design + xlsx 实现Excel多Sheet页导出功能

news2025/5/31 21:25:53

Vue + Ant Design 扩展:实现Excel多Sheet页导出功能

引言

在复杂业务场景中,单一Sheet页已无法满足数据展示需求。本文将演示如何基于Vue3 + Ant Design Vue + xlsx技术栈,实现以下高级导出功能:

  1. 动态多Sheet页生成
  2. 复杂数据集关联导出
  3. Sheet间样式统一控制
  4. 内存优化策略

通过实战案例,解决多维度数据报表导出的典型问题,打造专业级Excel导出方案。

一、多Sheet页核心场景

1.1 典型应用场景

场景类型示例说明技术要点
主从表结构订单主表 + 订单明细子表主从数据关联导出
分类汇总销售数据(按区域/时间多维度切片)动态Sheet命名策略
多维度报表财务三表(资产负债表/利润表/现金流量表)样式模板复用
附件式导出主数据 + 附件文档(图片/PDF)混合内容处理

1.2 技术选型对比

方案优点缺点
单Workbook多Sheet天然支持复杂关联内存管理要求高
多Workbook合并分布式处理简单破坏Excel原生结构
CSV分片+ZIP打包大数据量性能优异失去Excel格式控制能力

二、核心实现原理

2.1 工作簿架构设计

Workbook
├── Sheet1: 订单主表(100条)
├── Sheet2: 华东区明细(3000条)
├── Sheet3: 华南区明细(2500条)
└── Sheet4: 汇总分析(透视表)

2.2 内存管理模型

数据总量 → 分片策略 → 内存峰值 → 垃圾回收
   ↑         ↑        ↑         ↑
50,000条  5,000条/片  20MB     自动GC

2.3 异步处理流程

点击导出
初始化工作簿
创建主Sheet
填充主数据
是否需要明细?
创建明细Sheet
分片加载数据
追加到Sheet
创建汇总Sheet
生成文件

三、完整代码实现

3.1 多Sheet导出配置

// sheet-config.js
export const SHEET_CONFIG = {
  mainSheet: {
    name: '主数据',
    columns: ['id', 'name', 'totalAmount'],
    dataKey: 'mainData'
  },
  detailSheets: [
    {
      name: '华东区',
      filter: (record) => record.region === 'east',
      columns: ['orderNo', 'product', 'quantity']
    },
    {
      name: '华南区',
      filter: (record) => record.region === 'south',
      columns: ['orderNo', 'product', 'quantity']
    }
  ],
  summarySheet: {
    name: '汇总分析',
    pivotConfig: {
      rows: ['region'],
      columns: ['year'],
      values: ['totalAmount']
    }
  }
}

3.2 核心导出逻辑

<script setup>
import { ref } from 'vue'
import * as XLSX from 'xlsx/xlsx.mjs'
import { saveAs } from 'file-saver'
import { SHEET_CONFIG } from './sheet-config'

const exportMultiSheet = async (data) => {
  // 1. 初始化工作簿
  const workbook = XLSX.utils.book_new()
  
  // 2. 创建主Sheet
  const mainSheet = createSheetFromConfig(SHEET_CONFIG.mainSheet, data.mainData)
  XLSX.utils.book_append_sheet(workbook, mainSheet, SHEET_CONFIG.mainSheet.name)

  // 3. 创建明细Sheets
  for (const config of SHEET_CONFIG.detailSheets) {
    const filteredData = data.detailData.filter(config.filter)
    const detailSheet = createSheetFromConfig(config, filteredData)
    XLSX.utils.book_append_sheet(workbook, detailSheet, config.name)
  }

  // 4. 创建汇总Sheet
  const summaryData = createPivotTable(data.mainData, SHEET_CONFIG.summarySheet.pivotConfig)
  const summarySheet = XLSX.utils.aoa_to_sheet(summaryData)
  applySheetStyle(summarySheet, SUMMARY_STYLE)
  XLSX.utils.book_append_sheet(workbook, summarySheet, SHEET_CONFIG.summarySheet.name)

  // 5. 生成文件
  const blob = await generateBlob(workbook)
  saveAs(blob, `综合报表_${new Date().toISOString().slice(0,10)}.xlsx`)
}

const createSheetFromConfig = (config, data) => {
  const header = config.columns.map(col => ({ 
    v: col, 
    t: 's',
    s: HEADER_STYLE 
  }))
  
  const body = data.map(item => 
    config.columns.map(col => ({ 
      v: item[col],
      t: typeof item[col] === 'number' ? 'n' : 's'
    }))
  )

  const sheet = XLSX.utils.aoa_to_sheet([header, ...body])
  applySheetStyle(sheet, DEFAULT_STYLE)
  return sheet
}
</script>

3.3 样式管理系统

// 样式配置
const HEADER_STYLE = {
  font: { bold: true, color: { rgb: "FFFFFF" } },
  fill: { fgColor: { rgb: "4A90E2" } },
  alignment: { horizontal: 'center' }
}

const DEFAULT_STYLE = {
  border: {
    top: { style: 'thin' },
    bottom: { style: 'thin' },
    left: { style: 'thin' },
    right: { style: 'thin' }
  }
}

const SUMMARY_STYLE = {
  ...DEFAULT_STYLE,
  font: { bold: true },
  fill: { fgColor: { rgb: "F5A623" } }
}

// 样式应用工具
const applySheetStyle = (sheet, styleConfig) => {
  const range = XLSX.utils.decode_range(sheet['!ref'])
  for (let R = range.s.r; R <= range.e.r; ++R) {
    for (let C = range.s.c; C <= range.e.c; ++C) {
      const cellAddress = { r: R, c: C }
      const cellRef = XLSX.utils.encode_cell(cellAddress)
      if (!sheet[cellRef]) continue
      
      sheet[cellRef].s = {
        ...(sheet[cellRef].s || {}),
        ...styleConfig
      }
    }
  }
}

四、高级优化策略

4.1 动态Sheet管理

// 动态Sheet名称生成
const generateSheetName = (baseName, index) => {
  let name = baseName
  let suffix = 1
  while (workbook.SheetNames.includes(name)) {
    name = `${baseName}_${suffix++}`
  }
  return name
}

// 使用示例
let sheetName = generateSheetName('销售数据')
while (workbook.SheetNames.includes(sheetName)) {
  sheetName = generateSheetName('销售数据', suffix++)
}

4.2 大数据量优化

// 流式写入优化
const streamWrite = (workbook, data, config) => {
  return new Promise((resolve) => {
    let currentRow = 1
    const sheet = XLSX.utils.aoa_to_sheet([])
    XLSX.utils.book_append_sheet(workbook, sheet, config.name)

    const timer = setInterval(() => {
      const chunk = data.slice(currentRow, currentRow + 500)
      if (chunk.length === 0) {
        clearInterval(timer)
        resolve()
      }
      
      const body = chunk.map(item => 
        config.columns.map(col => ({ v: item[col] }))
      )
      XLSX.utils.sheet_add_aoa(sheet, body, { origin: currentRow + 1 })
      currentRow += 500
    }, 50)
  })
}

4.3 复杂表头处理

// 合并单元格配置
const createMergedHeader = (sheet, mergeConfig) => {
  mergeConfig.forEach(config => {
    sheet[`!merges`] = sheet[`!merges`] || []
    sheet[`!merges`].push({
      s: { r: config.startRow, c: config.startCol },
      e: { r: config.endRow, c: config.endCol }
    })
  })
}

// 使用示例
createMergedHeader(sheet, [
  { startRow: 0, startCol: 0, endRow: 1, endCol: 0 },
  { startRow: 0, startCol: 1, endRow: 0, endCol: 2 }
])

五、生产环境实践建议

  1. 内存监控:使用performance.memory监控堆内存使用
  2. 错误边界:添加try-catch块捕获导出异常
  3. Sheet索引:维护Sheet名称与数据的映射关系
  4. 格式预设:通过模板文件预设样式和公式
  5. 异步控制:使用AbortController实现可中断导出

总结

通过本文实现的多Sheet页导出方案,可获得以下提升:

  • 结构化展示:完美呈现复杂业务数据关系
  • 性能保障:流式处理支持10万+数据量导出
  • 样式统一:集中式样式管理确保视觉一致性
  • 扩展能力:动态配置支持快速迭代新报表

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

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

相关文章

DAY33 简单神经网络

你需要自行了解下MLP的概念。 你需要知道 梯度下降的思想激活函数的作用损失函数的作用优化器神经网络的概念 神经网络由于内部比较灵活&#xff0c;所以封装的比较浅&#xff0c;可以对模型做非常多的改进&#xff0c;而不像机器学习三行代码固定。 1. 神经网络的概念 (Th…

OBOO鸥柏丨2025年鸿蒙生态+国产操作系统触摸屏查询一体机核心股

在信创产业蓬勃发展的当下&#xff0c;OBOO鸥柏积极响应纯国产化号召&#xff0c;推出基于华为鸿蒙HarmonyOS操作系统的触摸屏查询一体机及室内外场景广告液晶显示屏一体机上市&#xff0c;OBOO鸥柏品牌旗下显示产品均采用国产芯片&#xff0c;接入终端控制端需支持安卓Windows…

【观成科技】Ymir勒索软件组织窃密木马RustyStealer加密通信分析

1.概述 Ymir勒索软件首次发现于2024年7月&#xff0c;采用ChaCha20加密算法对受害者文件进行加密&#xff0c;加密文件后缀为.6C5oy2dVr6。在攻击过程中&#xff0c;Ymir勒索组织利用名为RustyStealer的窃密木马获取受害企业的账号凭证&#xff0c;为后续横向移动和权限提升奠…

Vuer开源程序 是一个轻量级的可视化工具包,用于与动态 3D 和机器人数据进行交互。它支持 VR 和 AR,可以在移动设备上运行。

​一、软件介绍 文末提供程序和源码下载 Vuer开源程序 是一个轻量级的可视化工具包&#xff0c;用于与动态 3D 和机器人数据进行交互。它支持 VR 和 AR&#xff0c;可以在移动设备上运行。 二、Our features include: 我们的功能包括&#xff1a; light-weight and performa…

短视频一键搬运 v1.7.1|短视频无水印下载 一键去重

短视频一键搬运是一款全自动智能处理软件&#xff0c;专为短视频创作者设计。它自带去水印、改MD5码、视频去重、视频编辑等功能&#xff0c;能够高效处理大量视频&#xff0c;解放双手并降低成本。该软件支持从多个短视频平台无缝提取视频并去除水印&#xff0c;同时检测敏感词…

海上石油钻井平台人员安全管控解决方案

一、行业挑战与需求分析 海上钻井平台面临复杂环境风险&#xff08;如易燃易爆、金属干扰、极端气象&#xff09;和人员管理难题&#xff08;如定位模糊、应急响应延迟&#xff09;。传统RFID或蓝牙定位技术存在精度不足&#xff08;1-5米&#xff09;、抗干扰能力差等问题&am…

TEASER-plusplu Windows Mingw编译

编译记录&#xff1a; 1.下载该库 v2.0 链接1&#xff1a;https://github.com/MIT-SPARK/TEASER-plusplus 连接2&#xff1a;https://github.com/MIT-SPARK/TEASER-plusplus/releases 2.下载 googletest 链接&#xff1a;https://github.com/google/googletest/releases?page2…

tryhackme——Data Exfiltration

文章目录 一、网络拓扑二、数据泄露分类2.1 传统数据泄露2.2 C2通信2.3 隧道 三、隧道3.1 Exfiltration using TCP socket3.2 Exfiltration using SSH3.3 Exfiltrate using HTTP(S)HTTP隧道 3.4 Exfiltration using ICMP3.4.1 ICMP数据包结构3.4.2 MSF实现ICMP数据泄露3.4.3 IC…

阿里云服务器采用crontab定时任务使acme.sh全自动化申请续签免费SSL证书,并部署在Linux宝塔网站和雷池WAF

阿里云服务器安装Linux宝塔面板用于部署网站&#xff0c;又安装了雷池WAF用于防护网站&#xff0c;网站访问正常。可以参考文章&#xff1a;Linux服务器安装Linux宝塔面板并部署wordpress网站以及雷池WAF 本文介绍使用 acme.sh 通过 DNS API 全自动申请和续签免费Let’s Encry…

【华为鸿蒙电脑】首款鸿蒙电脑发布:MateBook Fold 非凡大师 MateBook Pro,擎云星河计划启动

文章目录 前言一、HUAWEI MateBook Fold 非凡大师&#xff08;一&#xff09;非凡设计&#xff08;二&#xff09;非凡显示&#xff08;三&#xff09;非凡科技&#xff08;四&#xff09;非凡系统&#xff08;五&#xff09;非凡体验 二、HUAWEI MateBook Pro三、预热&#xf…

SpringBoot Controller接收参数方式, @RequestMapping

一. 通过原始的HttpServletRequest对象获取请求参数 二. 通过Spring提供的RequestParam注解&#xff0c;将请求参数绑定给方法参数 三. 如果请求参数名与形参变量名相同&#xff0c;直接定义方法形参即可接收。(省略RequestParam) 四. JSON格式的请求参数(POST、PUT) 主要在PO…

端午节互动网站

端午节互动网站 项目介绍 这是一个基于 Vue 3 Vite 开发的端午节主题互动网站&#xff0c;旨在通过有趣的交互方式展示中国传统端午节文化。网站包含三个主要功能模块&#xff1a;端午节介绍、互动包粽子游戏和龙舟竞赛游戏。 预览网站&#xff1a;https://duanwujiekuaile…

react-color-palette源码解析

项目中用到了react-color-palette组件&#xff0c;以前对第三方组件都是不求甚解&#xff0c;这次想了解一下其实现细节。 简介 react-color-palette 是一个用于创建颜色调色板的 React 组件。它提供了一个简单易用的接口&#xff0c;让开发者可以轻松地创建和管理颜色调色板。…

在 Ubuntu 上安装 NVM (Node Version Manager) 的步骤

NVM (Node Version Manager) 是一个用于管理多个 Node.js 版本的工具&#xff0c;它允许您在同一台设备上安装、切换和管理不同版本的 Node.js。以下是在 Ubuntu 上安装 NVM 的详细步骤&#xff1a; 安装前准备 可先在windows上安装ubuntu 参考链接&#xff1a;https://blog.…

重温经典算法——插入排序

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 基本原理 插入排序是一种基于元素逐步插入的简单排序算法&#xff0c;其核心思想是将待排序序列分为已排序和未排序两部分&#xff0c;每次从未排序部分取出第一个元素&…

塔能科技:为多行业工厂量身定制精准节能方案

在当今追求可持续发展的时代&#xff0c;工厂能耗精准节能成为众多企业关注的焦点。塔能科技凭借先进的技术和丰富的经验&#xff0c;服务于广泛的行业客户&#xff0c;其中55.5%来自世界500强和上市公司。针对不同行业工厂的特点和需求&#xff0c;塔能提供了一系列行之有效的…

【实证分析】上市公司全要素生产率+5种测算方式(1999-2024年)

上市公司的全要素生产率&#xff08;TFP&#xff09;衡量企业在资本、劳动及中间投入之外&#xff0c;通过技术进步、管理效率和规模效应等因素提升产出的能力。与单纯的劳动生产率或资本生产率不同&#xff0c;TFP综合反映了企业创新能力、资源配置效率和组织优化水平&#xf…

弥散制氧机工作机制:高原低氧环境的氧浓度重构技术

弥散制氧机通过空气分离与智能扩散技术&#xff0c;将氧气均匀分布于封闭或半封闭空间&#xff0c;实现环境氧浓度的主动调控。其核心在于 “分子筛吸附动态均布智能反馈” 的协同作用机制&#xff0c;为高原、矿井、医疗等场景提供系统性氧环境解决方案。 一、空气分离&#x…

[Python] 避免 PyPDF2 写入 PDF 出现黑框问题:基于语言自动匹配系统字体的解决方案

在使用 Python 操作 PDF 文件时,尤其是在处理中文、日语等非拉丁字符语言时,常常会遇到一个令人头疼的问题——文字变成“黑框”或“方块”,这通常是由于缺少合适的字体支持所致。本文将介绍一种自动选择系统字体的方式,结合 PyPDF2 模块解决此类问题。 一、问题背景:黑框…

《基于Keepalived+LVS+Web+NFS的高可用集群搭建》

目 录 1 项目概述 1.1 项目背景 1.2 项目功能 2 项目的部署 2.1 部署环境介绍 2.2 项目的拓扑结构 2.3 项目环境调试 2.4 项目的部署 2.5 项目功能的验证 2.6 项目对应服务使用的日志 3 项目的注意事项 3.1 常见问题与解决方案 3.2 项目适用背…