当前位置: 首页 > news >正文

vue3 + xlsx 实现导出表格,动态获取表头和数据

针对第三方表格组件(如 vxe-table 或 el-table),通过其提供的 API 获取表头和数据,而不是直接操作 DOM。以下是针对 vxe-table 和 el-table 的通用导出函数封装:

npm install xlsx

1. 封装通用导出函数

import * as XLSX from 'xlsx'

/**
 * 导出表格数据为 Excel 文件
 * @param {Object} tableRef - 表格组件的 ref 引用
 * @param {String} fileName - 导出文件名(默认:export.xlsx)
 * @param {Object} options - 配置项(可选)
 * @param {Array} options.headers - 自定义表头(可选)
 * @param {Array} options.dataKeys - 自定义数据字段(可选)
 */
export const exportExcel = (tableRef, fileName = 'export.xlsx', options = {}) => {
  // 获取表头和数据
  let headers = []
  let data = []

  // 判断表格类型并提取数据
  if (tableRef.$options.name === 'VxeTable') {
    // vxe-table 处理逻辑
    headers = tableRef.getColumns().map(col => col.title)
    data = tableRef.getTableData().fullData
  } else if (tableRef.$options.name === 'ElTable') {
    // el-table 处理逻辑
    headers = tableRef.columns.map(col => col.label)
    data = tableRef.data
  } else {
    throw new Error('不支持的表格组件类型')
  }

  // 自定义表头和数据字段(如果传入 options)
  if (options.headers) {
    headers = options.headers
  }
  if (options.dataKeys) {
    data = data.map(item => {
      return options.dataKeys.reduce((obj, key) => {
        obj[key] = item[key]
        return obj
      }, {})
    })
  }

  // 构建工作表数据
  const worksheetData = [
    headers, // 表头行
    ...data.map(item => 
      headers.map(header => {
        // 自动匹配数据字段(假设表头与数据字段一一对应)
        const key = Object.keys(item).find(k => 
          k.toLowerCase() === header.toLowerCase()
        )
        return key ? item[key] : ''
      })
    )
  ]

  // 创建 workbook
  const workbook = XLSX.utils.book_new()
  const worksheet = XLSX.utils.aoa_to_sheet(worksheetData)
  
  // 添加样式
  worksheet['!cols'] = headers.map(() => ({ wch: 20 })) // 列宽
  
  // 组合并导出
  XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
  XLSX.writeFile(workbook, fileName)
}

2. 在组件中使用

vxe-table 示例

<template>
  <vxe-table ref="tableRef" :data="tableData">
    <vxe-column field="name" title="姓名" />
    <vxe-column field="age" title="年龄" />
    <vxe-column field="city" title="城市" />
  </vxe-table>

  <button @click="exportData">导出Excel</button>
</template>

<script setup>
import { ref } from 'vue'
import { exportExcel } from '@/utils/exportExcel'

const tableRef = ref(null)
const tableData = ref([
  { name: '张三', age: 25, city: '北京' },
  { name: '李四', age: 30, city: '上海' }
])

const exportData = () => {
  exportExcel(tableRef.value, '用户数据.xlsx')
}
</script>

el-table 示例

<template>
  <el-table ref="tableRef" :data="tableData">
    <el-table-column prop="name" label="姓名" />
    <el-table-column prop="age" label="年龄" />
    <el-table-column prop="city" label="城市" />
  </el-table>

  <button @click="exportData">导出Excel</button>
</template>

<script setup>
import { ref } from 'vue'
import { exportExcel } from '@/utils/exportExcel'

const tableRef = ref(null)
const tableData = ref([
  { name: '张三', age: 25, city: '北京' },
  { name: '李四', age: 30, city: '上海' }
])

const exportData = () => {
  exportExcel(tableRef.value, '用户数据.xlsx')
}
</script>

3. 高级用法

自定义表头和数据字段

const exportData = () => {
  exportExcel(tableRef.value, '用户数据.xlsx', {
    headers: ['姓名', '城市'], // 自定义表头
    dataKeys: ['name', 'city'] // 自定义数据字段
  })
}

导出特定数据

const exportData = () => {
  const filteredData = tableData.value.filter(item => item.age > 25)
  exportExcel(tableRef.value, '用户数据.xlsx', {
    data: filteredData // 导出过滤后的数据
  })
}

4. 注意事项

  1. 表头与数据字段匹配:

     默认情况下,表头(title 或 label)与数据字段(field 或 prop)需要一一对应。
    
     如果表头与字段不一致,可以通过 options.headers 和 options.dataKeys 自定义。
    
  2. 大数据量导出:

     如果数据量较大,建议分批次导出或添加加载提示。
    
  3. 样式优化:

     可以通过 worksheet['!cols'] 调整列宽,或使用 XLSX.utils.sheet_add_json 添加样式。
    

相关文章:

  • Linux笔记---一切皆文件
  • Java测试框架Mockito快速入门
  • 数字人源码/数字人系统源码部署方案详解!包含数字人oem部署方案
  • 【我的 PWN 学习手札】House of Kiwi
  • 904. 水果成篮
  • 前端实现rsa加密功能
  • 线程池的介绍
  • Linux-ftrace-双nop机制的实现
  • c# winform程序 vs2022 打包生成安装包
  • # 代码写作风格:优雅编程的艺术
  • 一文掌握 Scrapy 框架的详细使用,包括实战案例
  • 【SQL】掌握SQL查询技巧:数据分组与排序
  • 优艾智合机器人日本子公司成立,加速推进国际化布局
  • Redis大key
  • Zynq移植canopen协议站canfestival+控制电机运动
  • 使用AI后为什么思考会变得困难?
  • 2.4 自动化评测答疑机器人的表现-大模型ACP模拟题-真题
  • k8s拉取harbor镜像部署
  • 3 算法1-4 过河卒
  • CineMaster: 用于电影文本到视频生成的 3D 感知且可控的框架。
  • 白云做网站SEO/手机一键优化
  • 网站购物车功能/国内免费顶级域名注册
  • 美食网站建设/整合营销包括哪些内容
  • 网站建设怎么进行一级域名申请/网络营销推广计划
  • 模板搭建网站/站长工具综合权重查询
  • 公司网站备案需要什么/成都疫情最新消息