Vue使用vxe-table导出和自定义Excel样式的详细教程

 更新时间:2026年05月29日 08:47:38   作者:仰望.  
vxe-table 不仅支持将表格数据导出为 .xlsx 文件,还提供了强大的自定义样式能力,因此本文给大家介绍了Vue使用vxe-table导出和自定义Excel样式的详细教程,需要的朋友可以参考下

引言

vxe-table 不仅支持将表格数据导出为 .xlsx 文件,还提供了强大的自定义样式能力。通过 exportConfig.sheetMethod 钩子,你可以直接操作底层的 ExcelJS 工作表对象,对导出的 Excel 进行精细化样式设置,包括边框、字体、背景色、列宽、行高、超链接、图片等。

  • 前置准备:请确保已安装并注册 @vxe-ui/plugin-export-xlsx 和 exceljs 插件。

核心配置:sheetMethod 钩子

在 gridOptions.exportConfig 中定义 sheetMethod 函数,它会在导出过程中被调用,并接收包含 worksheet(工作表对象)、workbook(工作簿对象)等参数。在此函数内,你可以使用 ExcelJS 的 API 修改样式。

exportConfig: {
  sheetMethod(params) {
    const { worksheet, workbook } = params
    // 自定义样式逻辑
  }
}

示例

设置边框

为所有单元格添加红色细边框:

<template>
  <div>
    <vxe-button @click="exportEvent">点击导出</vxe-button>
    <vxe-grid ref="gridRef" v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const gridRef = ref()

const gridOptions = reactive({
  border: true,
  showFooter: true,
  exportConfig: {
    sheetMethod(params) {
      const { worksheet } = params
      worksheet.eachRow((excelRow) => {
        excelRow.eachCell((excelCell) => {
          // 设置单元格边框
          excelCell.border = {
            top: {
              style: 'thin',
              color: {
                argb: 'ff0000'
              }
            },
            left: {
              style: 'thin',
              color: {
                argb: 'ff0000'
              }
            },
            bottom: {
              style: 'thin',
              color: {
                argb: 'ff0000'
              }
            },
            right: {
              style: 'thin',
              color: {
                argb: 'ff0000'
              }
            }
          }
        })
      })
    }
  },
  columns: [
    { field: 'seq', type: 'seq', width: 70 },
    {
      title: '分组1',
      children: [
        { field: 'name', title: 'Name' },
        { field: 'role', title: 'Role' }
      ]
    },
    { field: 'sex', title: 'Sex' },
    { field: 'no1', title: 'NO1' },
    { field: 'no2', title: 'NO2 String', cellType: 'string' }
  ],
  data: [
    { id: 10001, name: '张三', role: 'Develop', sex: 'Man', no1: '028', no2: '028' },
    { id: 10002, name: '李四', role: '研发', sex: 'Women', no1: '220', no2: '220' },
    { id: 10003, name: '王五', role: '产品经理', sex: 'Man', no1: '003200', no2: '003200' },
    { id: 10004, name: '老六', role: 'Designer', sex: 'Women', no1: '02040', no2: '02040' }
  ],
  footerData: [{ seq: '合计', name: '12人', no1: '356' }]
})

const exportEvent = () => {
  const $grid = gridRef.value
  if ($grid) {
    $grid.exportData({
      type: 'xlsx'
    })
  }
}
</script>

设置字体

将所有单元格字体设为红色、粗体、16号:

<template>
  <div>
    <vxe-button @click="exportEvent">点击导出</vxe-button>
    <vxe-grid ref="gridRef" v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const gridRef = ref()

const gridOptions = reactive({
  border: true,
  showFooter: true,
  exportConfig: {
    sheetMethod(params) {
      const { worksheet } = params
      worksheet.eachRow((excelRow) => {
        excelRow.eachCell((excelCell) => {
          // 设置单元格字体
          excelCell.font = {
            bold: true,
            size: 16,
            color: {
              argb: 'ff0000'
            }
          }
        })
      })
    }
  },
  columns: [
    { field: 'seq', type: 'seq', width: 70 },
    {
      title: '分组1',
      children: [
        { field: 'name', title: 'Name' },
        { field: 'role', title: 'Role' }
      ]
    },
    { field: 'sex', title: 'Sex' },
    { field: 'no1', title: 'NO1' },
    { field: 'no2', title: 'NO2 String', cellType: 'string' }
  ],
  data: [
    { id: 10001, name: '张三', role: 'Develop', sex: 'Man', no1: '028', no2: '028' },
    { id: 10002, name: '李四', role: '研发', sex: 'Women', no1: '220', no2: '220' },
    { id: 10003, name: '王五', role: '产品经理', sex: 'Man', no1: '003200', no2: '003200' },
    { id: 10004, name: '老六', role: 'Designer', sex: 'Women', no1: '02040', no2: '02040' }
  ],
  footerData: [{ seq: '合计', name: '12人', no1: '356' }]
})

const exportEvent = () => {
  const $grid = gridRef.value
  if ($grid) {
    $grid.exportData({
      type: 'xlsx'
    })
  }
}
</script>

设置表头背景

将前 3 行(表头区域)填充为淡蓝色背景

<template>
  <div>
    <vxe-button @click="exportEvent">点击导出</vxe-button>
    <vxe-grid ref="gridRef" v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const gridRef = ref()

const gridOptions = reactive({
  border: true,
  showFooter: true,
  exportConfig: {
    sheetMethod(params) {
      const { worksheet } = params
      worksheet.eachRow((excelRow, rowIndex) => {
        if (rowIndex <= 2) {
          excelRow.eachCell((excelCell) => {
            // 填充单元格背景
            excelCell.fill = {
              type: 'pattern',
              pattern: 'solid',
              fgColor: {
                argb: 'c5d9f1'
              }
            }
          })
        }
      })
    }
  },
  columns: [
    { field: 'seq', type: 'seq', width: 70 },
    {
      title: '分组1',
      children: [
        { field: 'name', title: 'Name' },
        { field: 'role', title: 'Role' }
      ]
    },
    { field: 'sex', title: 'Sex' },
    { field: 'no1', title: 'NO1' },
    { field: 'no2', title: 'NO2 String', cellType: 'string' }
  ],
  data: [
    { id: 10001, name: '张三', role: 'Develop', sex: 'Man', no1: '028', no2: '028' },
    { id: 10002, name: '李四', role: '研发', sex: 'Women', no1: '220', no2: '220' },
    { id: 10003, name: '王五', role: '产品经理', sex: 'Man', no1: '003200', no2: '003200' },
    { id: 10004, name: '老六', role: 'Designer', sex: 'Women', no1: '02040', no2: '02040' }
  ],
  footerData: [{ seq: '合计', name: '12人', no1: '356' }]
})

const exportEvent = () => {
  const $grid = gridRef.value
  if ($grid) {
    $grid.exportData({
      type: 'xlsx'
    })
  }
}
</script>

设置列宽

将所有列宽设置为 16:

<template>
  <div>
    <vxe-button @click="exportEvent">点击导出</vxe-button>
    <vxe-grid ref="gridRef" v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const gridRef = ref()

const gridOptions = reactive({
  border: true,
  showFooter: true,
  exportConfig: {
    async sheetMethod(params) {
      const { worksheet } = params
      worksheet.columns.forEach((sheetColumn) => {
        // 设置列宽
        sheetColumn.width = 16
      })
    }
  },
  columns: [
    { field: 'seq', type: 'seq', width: 70 },
    {
      title: '分组1',
      children: [
        { field: 'name', title: 'Name' },
        { field: 'role', title: 'Role' }
      ]
    },
    { field: 'sex', title: 'Sex' },
    { field: 'no1', title: 'NO1' },
    { field: 'no2', title: 'NO2 String', cellType: 'string' }
  ],
  data: [
    { id: 10001, name: '张三', role: 'Develop', sex: 'Man', no1: '028', no2: '028' },
    { id: 10002, name: '李四', role: '研发', sex: 'Women', no1: '220', no2: '220' },
    { id: 10003, name: '王五', role: '产品经理', sex: 'Man', no1: '003200', no2: '003200' },
    { id: 10004, name: '老六', role: 'Designer', sex: 'Women', no1: '02040', no2: '02040' }
  ],
  footerData: [{ seq: '合计', name: '12人', no1: '356' }]
})

const exportEvent = () => {
  const $grid = gridRef.value
  if ($grid) {
    $grid.exportData({
      type: 'xlsx'
    })
  }
}
</script>

设置行高

将所有数据行高设置为 60(单位:磅):

<template>
  <div>
    <vxe-button @click="exportEvent">点击导出</vxe-button>
    <vxe-grid ref="gridRef" v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const gridRef = ref()

const gridOptions = reactive({
  border: true,
  showFooter: true,
  exportConfig: {
    async sheetMethod(params) {
      const { worksheet } = params
      worksheet.eachRow((excelRow) => {
        // 设置行高
        excelRow.height = 60
      })
    }
  },
  columns: [
    { field: 'seq', type: 'seq', width: 70 },
    {
      title: '分组1',
      children: [
        { field: 'name', title: 'Name' },
        { field: 'role', title: 'Role' }
      ]
    },
    { field: 'sex', title: 'Sex' },
    { field: 'no1', title: 'NO1' },
    { field: 'no2', title: 'NO2 String', cellType: 'string' }
  ],
  data: [
    { id: 10001, name: '张三', role: 'Develop', sex: 'Man', no1: '028', no2: '028' },
    { id: 10002, name: '李四', role: '研发', sex: 'Women', no1: '220', no2: '220' },
    { id: 10003, name: '王五', role: '产品经理', sex: 'Man', no1: '003200', no2: '003200' },
    { id: 10004, name: '老六', role: 'Designer', sex: 'Women', no1: '02040', no2: '02040' }
  ],
  footerData: [{ seq: '合计', name: '12人', no1: '356' }]
})

const exportEvent = () => {
  const $grid = gridRef.value
  if ($grid) {
    $grid.exportData({
      type: 'xlsx'
    })
  }
}
</script>

设置超链接

为第 2 列(Name 列)的每个数据单元格添加超链接:

<template>
  <div>
    <vxe-button @click="exportEvent">点击导出</vxe-button>
    <vxe-grid ref="gridRef" v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const gridRef = ref()

const gridOptions = reactive({
  border: true,
  showFooter: true,
  exportConfig: {
    sheetMethod(params) {
      const { worksheet } = params
      worksheet.eachRow((excelRow, rowIndex) => {
        if (rowIndex > 2) {
          excelRow.eachCell((excelCell, columnIndex) => {
            if (columnIndex === 2) {
              // 设置指定单元格为超链接
              excelCell.value = {
                text: `${excelCell.value}`,
                hyperlink: 'https://vxeui.com',
                tooltip: 'vxeui.com'
              }
              // 设置单元格字体
              excelCell.font = {
                color: {
                  argb: '0000ff'
                }
              }
            }
          })
        }
      })
    }
  },
  columns: [
    { field: 'seq', type: 'seq', width: 70 },
    {
      title: '分组1',
      children: [
        { field: 'name', title: 'Name' },
        { field: 'role', title: 'Role' }
      ]
    },
    { field: 'sex', title: 'Sex' },
    { field: 'no1', title: 'NO1' },
    { field: 'no2', title: 'NO2 String', cellType: 'string' }
  ],
  data: [
    { id: 10001, name: '张三', role: 'Develop', sex: 'Man', no1: '028', no2: '028' },
    { id: 10002, name: '李四', role: '研发', sex: 'Women', no1: '220', no2: '220' },
    { id: 10003, name: '王五', role: '产品经理', sex: 'Man', no1: '003200', no2: '003200' },
    { id: 10004, name: '老六', role: 'Designer', sex: 'Women', no1: '02040', no2: '02040' }
  ],
  footerData: [{ seq: '合计', name: '12人', no1: '356' }]
})

const exportEvent = () => {
  const $grid = gridRef.value
  if ($grid) {
    $grid.exportData({
      type: 'xlsx'
    })
  }
}
</script>

添加图片

在数据行的第 2 列单元格位置插入 Logo 图片(需确保图片服务器支持跨域):

<template>
  <div>
    <vxe-button @click="exportEvent">点击导出</vxe-button>
    <vxe-grid ref="gridRef" v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const gridRef = ref()

const gridOptions = reactive({
  border: true,
  showFooter: true,
  exportConfig: {
    async sheetMethod(params) {
      const { worksheet, workbook } = params
      // 加载图片
      const buffer1 = await fetch('https://vxeui.com/logo.png').then((res) => res.arrayBuffer())
      const imageId1 = workbook.addImage({
        buffer: buffer1,
        extension: 'png'
      })
      worksheet.eachRow((excelRow, rowIndex) => {
        if (rowIndex > 2) {
          // 设置行高
          excelRow.height = 60
          excelRow.eachCell((excelCell, columnIndex) => {
            if (columnIndex === 2) {
              // 将图片添加到单元格
              worksheet.addImage(imageId1, {
                tl: { col: columnIndex - 1, row: rowIndex - 1 },
                ext: { width: 40, height: 40 }
              })
            }
          })
        }
      })
    }
  },
  columns: [
    { field: 'seq', type: 'seq', width: 70 },
    {
      title: '分组1',
      children: [
        { field: 'name', title: 'Name' },
        { field: 'role', title: 'Role' }
      ]
    },
    { field: 'sex', title: 'Sex' },
    { field: 'no1', title: 'NO1' },
    { field: 'no2', title: 'NO2 String', cellType: 'string' }
  ],
  data: [
    { id: 10001, name: '张三', role: 'Develop', sex: 'Man', no1: '028', no2: '028' },
    { id: 10002, name: '李四', role: '研发', sex: 'Women', no1: '220', no2: '220' },
    { id: 10003, name: '王五', role: '产品经理', sex: 'Man', no1: '003200', no2: '003200' },
    { id: 10004, name: '老六', role: 'Designer', sex: 'Women', no1: '02040', no2: '02040' }
  ],
  footerData: [{ seq: '合计', name: '12人', no1: '356' }]
})

const exportEvent = () => {
  const $grid = gridRef.value
  if ($grid) {
    $grid.exportData({
      type: 'xlsx'
    })
  }
}
</script>

说明

事项说明
异步处理如果 sheetMethod 中包含异步操作(如 fetch 图片),务必使用 async 函数,并等待完成。
行/列索引偏移worksheet.eachRow 回调中 rowIndex 从 1 开始(1 为第一行)。列索引同样从 1 开始。
图片跨域使用 fetch 加载图片时,需确保图片服务器支持跨域,否则无法获取图片内容。
性能考虑大表格(如超过 1000 行)时,遍历所有单元格设置样式可能耗时较长,建议按需设置,或仅对特定区域操作。
样式覆盖某些全局样式(如列宽)如果在 sheetMethod 中设置,会覆盖默认导出样式;多步设置时注意顺序。
ExcelJS 版本兼容插件依赖 exceljs,建议版本 ^4.3.0,不同版本 API 可能有细微差异,请查阅对应文档。

以上就是Vue使用vxe-table导出和自定义Excel样式的详细教程的详细内容,更多关于Vue vxe-table导出Excel的资料请关注脚本之家其它相关文章!

相关文章

  • nginx部署多个vue项目的方法示例

    nginx部署多个vue项目的方法示例

    这篇文章主要介绍了nginx部署多个vue项目的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • vue3响应式实现readonly从零开始教程

    vue3响应式实现readonly从零开始教程

    这篇文章主要为大家介绍了vue3响应式实现readonly从零开始教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 手把手教你使用Vue实现弹窗效果

    手把手教你使用Vue实现弹窗效果

    在vue中弹窗是常用的组件之一,可以用来展示警告、成功提示和错误信息等内容,这篇文章主要给大家介绍了关于如何使用Vue实现弹窗效果的相关资料,需要的朋友可以参考下
    2024-02-02
  • Vue父子组件通讯的四种方法详解

    Vue父子组件通讯的四种方法详解

    父子组件通讯是指在前端开发的组件化架构中,父组件与子组件之间互相传递数据和触发功能的一种机制,这种机制使得组件能够保持独立性的同时,也能协同工作,本文给大家介绍了Vue父子组件通讯的四种方法,需要的朋友可以参考下
    2024-07-07
  • vscode下vue项目中eslint的使用方法

    vscode下vue项目中eslint的使用方法

    这篇文章主要给大家介绍了关于vscode下vue项目中eslint的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • Vue-Access-Control 前端用户权限控制解决方案

    Vue-Access-Control 前端用户权限控制解决方案

    Vue-Access-Control是一套基于Vue/Vue-Router/axios 实现的前端用户权限控制解决方案。这篇文章主要介绍了Vue-Access-Control:前端用户权限控制解决方案,需要的朋友可以参考下
    2017-12-12
  • vue3中安装并且使用Tailwind CSS的完整步骤

    vue3中安装并且使用Tailwind CSS的完整步骤

    这篇文章主要介绍了vue3中安装并且使用Tailwind CSS的完整步骤,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-04-04
  • 安装vue3开发者工具但控制台没有显示出vue选项的解决

    安装vue3开发者工具但控制台没有显示出vue选项的解决

    这篇文章主要介绍了安装vue3开发者工具但控制台没有显示出vue选项的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Vue+canvas实现视频截图功能

    Vue+canvas实现视频截图功能

    这篇文章主要为大家详细介绍了Vue+canvas实现视频截图功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • Vue字符串中如何添加多个空格

    Vue字符串中如何添加多个空格

    这篇文章主要介绍了Vue字符串中如何添加多个空格问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01

最新评论