vue使用xlsx和xlsx-style导出excel文件

1、引入

npm install xlsx

npm install xlsx-style

这俩库同时导入一起使用会报错

2. 解决报错

打开node_ modules报找到xlsx,复制xlsx.full.min.js文件

引入到html文件中

然后解决xlsx-style的报错问题
打开项目根目录的vue.config.js文件,写入以下代码

​
module.exports = {
    chainWebpack(config) {
    config.externals({ './cptable': 'var cptable' })
    }
}

​

 3. 导出数据

封装函数

import XLSXStyle from "xlsx-style"; // 使用 XLSXStyle 引入

// 通用 Excel 导出工具函数
export function exportToExcel(data, columnWidths, filename) {
  if (!data || !Array.isArray(data) || data.length === 0) {
    console.warn("数据不能为空");
    return;
  }

  // 将数据转换为 Excel 的 sheet
  const sheet = XLSX.utils.aoa_to_sheet(data);

  // 设置单元格样式:水平居中、垂直居中、边框
  const borderAll = {
    top: { style: "thin" },
    bottom: { style: "thin" },
    left: { style: "thin" },
    right: { style: "thin" },
  };

  // 遍历所有单元格,应用样式
  for (const key in sheet) {
    if (sheet.hasOwnProperty(key) && key[0] !== '!') {
      sheet[key].s = {
        alignment: {
          horizontal: "center",  // 水平居中
          vertical: "center",    // 垂直居中
        },
        font: {
          name: "Arial",  // 字体
          sz: 12,         // 字体大小
        },
        border: borderAll,  // 边框
      };
    }
  }

  // 设置列宽
  sheet['!cols'] = columnWidths.map(width => ({ wpx: width }));

  // 调用下载函数
  openDownloadDialog(sheet2blob(sheet), `${filename}.xlsx`);
}

/**
 * 打开下载对话框的方法
 * @param {Blob} url Blob 对象
 * @param {String} saveName 文件名
 */
function openDownloadDialog(url, saveName) {
  const aLink = document.createElement("a");
  const blob = url instanceof Blob ? URL.createObjectURL(url) : url;
  aLink.href = blob;
  aLink.download = saveName || "download.xlsx";
  aLink.click();
}

/**
 * 将sheet对象转换为blob对象
 * @param {Object} sheet sheet对象
 * @param {String} sheetName sheet名称,默认 "Sheet1"
 * @returns {Blob}
 */
function sheet2blob(sheet, sheetName = "Sheet1") {
  const workbook = {
    SheetNames: [sheetName],
    Sheets: { [sheetName]: sheet },
  };

  const wopts = {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  };

  const wbout = XLSXStyle.write(workbook, wopts);

  // 将输出的文件内容转换为 Blob 对象
  function s2ab(s) {
    const buf = new ArrayBuffer(s.length);
    const view = new Uint8Array(buf);
    for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
    return buf;
  }

  return new Blob([s2ab(wbout)], { type: 'application/octet-stream' });
}

vue组件中使用

<template>
  <div class="page">
    <el-button type="primary" @click="exportExcel">下载Excel</el-button>
  </div>
</template>

<script>
import { exportToExcel } from '@/utils/excel.js' //写直接的路径

export default {
  methods: {
    // 下载excel
    exportExcel() {
      const data = [
        ['年份', '省份/城市', '数量', '增长率'],
        ['2021', '北京', 100, '20%'],
        ['2021', '上海', 200, '15%'],
        ['2022', '广州', 150, '10%']
      ];

      const columnWidths = [100, 200, 100, 100];  // 每列的宽度
      const filename = 'data.xlsx';

      exportToExcel(data, columnWidths, filename);
    },

  }
};
</script>

### 安装依赖 在 Vue3 项目中实现导出 Excel 文件的功能,可以使用 `xlsx` `file-saver` 这两个库。首先需要安装它们: ```bash npm install xlsx file-saver ``` 安装完成后,可以在项目中引入这两个库以供后续使用: ```javascript import * as XLSX from 'xlsx'; import FileSaver from 'file-saver'; ``` ### 导出方法实现 为了方便复用,可以将导出逻辑封装到一个工具函数中。例如,创建一个 `utils` 文件夹,并在其中添加一个 `Export2Excel.js` 文件用于处理数据转换文件保存: ```javascript import * as XLSX from 'xlsx'; import FileSaver from 'file-saver'; export const exportToExcel = (data, filename, sheetName) => { const worksheet = XLSX.utils.aoa_to_sheet(data); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, sheetName || 'Sheet1'); const wbout = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); try { FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${filename}.xlsx`); } catch (e) { if (typeof console !== 'undefined') console.log(e, wbout); } }; ``` 在组件中调用该方法: ```javascript import { exportToExcel } from '@/utils/Export2Excel'; const handleExport = () => { const data = [ ['ID', '名称', '数量'], [1, '商品A', 10], [2, '商品B', 20] ]; exportToExcel(data, '库存数据', '库存'); }; ``` ### 从表格导出数据 如果需要从页面上的表格导出数据,可以使用 `xlsx` 提供的 `table_to_book` 方法。例如,导出一个 `el-table` 的数据: ```html <template> <el-table id="exportXlsx" :data="tableData"> <el-table-column prop="date" label="日期"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> </el-table> <el-button @click="exportExcel">导出 Excel</el-button> </template> ``` ```javascript import * as XLSX from 'xlsx'; import FileSaver from 'file-saver'; export default { data() { return { tableData: [ { date: '2023-01-01', name: '张三', address: '北京市' }, { date: '2023-01-02', name: '李四', address: '上海市' } ] }; }, methods: { exportExcel() { const wb = XLSX.utils.table_to_book(document.getElementById('exportXlsx'), { raw: true }); const wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' }); try { FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), '表格数据.xlsx'); } catch (e) { if (typeof console !== 'undefined') console.log(e, wbout); } return wbout; } } }; ``` ### 自定义导出组件 对于需要多次复用导出功能的项目,可以封装一个通用的 Excel 导出组件。例如,在一个局部插件中实现导出功能: ```javascript import * as XLSX from 'xlsx'; import FileSaver from 'file-saver'; export const open = (list, dataList, fileName) => { const headers = list.filter(item => item.show).map(item => item.label); const fields = list.filter(item => item.show).map(item => item.field); const data = [headers]; dataList.forEach(item => { const row = fields.map(field => item[field]); data.push(row); }); const worksheet = XLSX.utils.aoa_to_sheet(data); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); const wbout = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); try { FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${fileName}.xlsx`); } catch (e) { if (typeof console !== 'undefined') console.log(e, wbout); } }; ``` 在组件中使用该插件: ```html <template> <div> <h1>欢迎使用局部导出 Excel 插件</h1> <button @click="showModal">打开弹出窗口</button> </div> </template> <script setup> import { ref } from 'vue'; import LoadingService from '../../plugIn/modalPlugin'; const data_title = ref([ { field: 'badge', show: true, label: '工号' }, { field: 'name', show: true, label: '员工姓名' } ]); const data_list = ref([]); const showModal = () => { let list = JSON.parse(JSON.stringify(data_title.value)); let dataList = data_list.value; let fileName = '文件名称'; LoadingService.open(list, dataList, fileName); }; </script> ``` ### 相关问题
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值