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

1、引入

npm install xlsx
 
npm install xlsx-style

我使用的对应版本如下图

2、解决报错

打开node_ modules文件下找到xlsx,复制xlsx.full.min.js文件,放到对应文件并在index.html中引入

引入到html文件中

然后解决xlsx-style的报错问题

vue解决问题:

打开项目根目录的vue.config.js文件,没有就新建一个,写入以下代码

module.exports = {
	configureWebpack: {
		resolve: {
			fallback: {
				fs: false // 禁用fs模块 否则 xlsx-style 模块会报错
			}
		},
		externals: {
			'./cptable': 'var cptable' // 去除 xlsx-style 模块的报错
		}
	},
}

react解决问题如下:(查看项目中是否存在 craco.config.js、config-overrides.js 其中的一种)

如果存在craco.config.js文件,则在craco.config.js文件中修改配置,如下

module.exports = {
	webpack: {
		configure: (webpackConfig, { env, paths }) => {
			webpackConfig.resolve.fallback = {
				crypto: false, // 禁用crypto模块 否则控制台会有警告
				fs: false, // 禁用fs模块 否则 xlsx-style 模块会报错
			}
			webpackConfig.externals = {
				'./cptable': 'var cptable' // 去除 xlsx-style 模块的报错
			}
			return webpackConfig
		},
	},
};

如果存在config-overrides.js 文件,就在config-overrides.js文件中修改以下配置

const {
  override,
} = require("customize-cra");


module.exports = override(
  (config, env) => {
    // 设置 resolve.fallback
    config.resolve.fallback = {
      crypto: false, // 或者提供一个 polyfill,如 'crypto-browserify'
      fs: false, // fs 模块在浏览器中通常不可用,设置为 false 表示不尝试加载它
      // 可以添加其他需要 fallback 的模块
    };
    // 设置 externals
    config.externals = {
      './cptable': 'var cptable' // 去除 xlsx-style 模块的报错
    };
    return config;
  },

);

如果以上两个文件都不存在,则打开项目根目录的webpack.config.js文件,没有新建一个,写入以下代码

module.exports = {
    resolve: {
        fallback: {
            fs: false // 禁用fs模块 否则 xlsx-style 模块会报错
        }
    },
    externals: {
        './cptable': 'var cptable' // 去除 xlsx-style 模块的报错
    },
};

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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值