Vue实现导出Excel的几种方法

在Vue项目中,导出Excel是一个常见的需求。根据不同的业务场景,我们可以选择不同的实现方式。网上找了几种常用的方法,特此记录。

1. 纯前端实现(使用xlsx库)

这种方法适合数据量不大,完全在前端处理的场景。

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

<script>
import XLSX from 'xlsx';

export default {
  methods: {
    handleExport() {
      // 准备数据
      const exportData = [
        ['序号', '姓名', '部门', '入职日期'],
        [1, '张三', '技术部', '2020-05-10'],
        [2, '李四', '市场部', '2019-11-15'],
        [3, '王五', '人事部', '2021-03-22']
      ];
      
      // 创建工作簿
      const workbook = XLSX.utils.book_new();
      const worksheet = XLSX.utils.aoa_to_sheet(exportData);
      
      // 添加工作表到工作簿
      XLSX.utils.book_append_sheet(workbook, worksheet, '员工信息');
      
      // 导出文件
      XLSX.writeFile(workbook, '员工信息表.xlsx');
    }
  }
};
</script>

2. 前后端配合实现

对于数据量较大或需要后端处理的场景,可以采用这种方式。

前端代码:

<template>
  <button @click="downloadExcel">下载报表</button>
</template>

<script>
import axios from 'axios';

export default {
  methods: {
    async downloadExcel() {
      try {
        const response = await axios.get('/api/export/employee', {
          responseType: 'blob'
        });
        
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', '员工报表.xlsx');
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      } catch (error) {
        console.error('导出失败:', error);
      }
    }
  }
};
</script>

后端示例(Node.js):

const express = require('express');
const XLSX = require('xlsx');
const app = express();

app.get('/api/export/employee', (req, res) => {
  // 模拟从数据库获取数据
  const data = [
    { id: 1, name: '张三', department: '技术部', joinDate: '2020-05-10' },
    { id: 2, name: '李四', department: '市场部', joinDate: '2019-11-15' }
  ];
  
  // 转换为工作表需要的格式
  const worksheetData = data.map(item => [
    item.id, 
    item.name, 
    item.department, 
    item.joinDate
  ]);
  
  // 添加表头
  worksheetData.unshift(['ID', '姓名', '部门', '入职日期']);
  
  // 创建工作表
  const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, worksheet, '员工数据');
  
  // 生成Excel文件
  const buffer = XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' });
  
  // 设置响应头
  res.setHeader('Content-Disposition', 'attachment; filename=employees.xlsx');
  res.type('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  res.send(buffer);
});

app.listen(3000);

3. 使用FileSaver.js增强下载功能

<template>
  <button @click="exportWithFileSaver">导出带样式的Excel</button>
</template>

<script>
import XLSX from 'xlsx';
import { saveAs } from 'file-saver';

export default {
  methods: {
    exportWithFileSaver() {
      const data = [
        ['产品', '销量', '销售额'],
        ['手机', 120, 360000],
        ['电脑', 85, 425000],
        ['平板', 65, 162500]
      ];
      
      const worksheet = XLSX.utils.aoa_to_sheet(data);
      const workbook = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(workbook, worksheet, '销售数据');
      
      // 生成Excel文件
      const excelData = XLSX.write(workbook, {
        type: 'array',
        bookType: 'xlsx'
      });
      
      // 使用FileSaver保存文件
      const blob = new Blob([excelData], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      });
      
      saveAs(blob, '销售报表.xlsx');
    }
  }
};
</script>

4. 导出HTML表格为Excel

适合已经渲染好的表格数据导出。

<template>
  <div>
    <table ref="exportTable">
      <thead>
        <tr>
          <th>城市</th>
          <th>人口(万)</th>
          <th>GDP(亿元)</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item, index) in cityData" :key="index">
          <td>{{ item.name }}</td>
          <td>{{ item.population }}</td>
          <td>{{ item.gdp }}</td>
        </tr>
      </tbody>
    </table>
    <button @click="exportTable">导出当前表格</button>
  </div>
</template>

<script>
import html2excel from 'html2excel';

export default {
  data() {
    return {
      cityData: [
        { name: '北京', population: 2171, gdp: 36103 },
        { name: '上海', population: 2424, gdp: 38701 },
        { name: '广州', population: 1868, gdp: 25019 }
      ]
    };
  },
  methods: {
    exportTable() {
      html2excel(this.$refs.exportTable, {
        name: '城市数据.xlsx',
        sheet: {
          name: 'Sheet 1'
        }
      });
    }
  }
};
</script>

方法对比

  1. 纯前端xlsx方案:

    • 优点:不依赖后端,实现简单
    • 缺点:大数据量可能影响性能
    • 适用场景:数据量小,需要快速实现的场景
  2. 前后端配合方案:

    • 优点:后端处理大数据性能好
    • 缺点:需要前后端协作
    • 适用场景:数据量大或需要后端处理的复杂报表
  3. FileSaver增强方案:

    • 优点:提供更灵活的下载控制
    • 缺点:需要额外引入库
    • 适用场景:需要特殊下载需求的场景
  4. HTML表格导出方案:

    • 优点:直接导出已渲染的表格
    • 缺点:样式可能不完全一致
    • 适用场景:已有表格数据直接导出的需求

选择哪种方案取决于具体项目需求、数据量大小和团队协作方式。对于简单的导出需求,纯前端方案通常就足够了;对于复杂的报表或大数据量,建议采用前后端配合的方案。

posted @ 2025-06-12 16:12  99客服  阅读(1028)  评论(0)    收藏  举报