最简单的js导出excel文件和axios下载文件流

导出excel文件最简单方案,前端生成文件使用xlsx插件,解析后端接口文件流使用axios
建立utils/excel.ts并将该文件代码复制进去

import { ElMessage } from 'element-plus';
import * as XLSX from 'xlsx';

export interface HandleExportExcelType {
  header: string[]; // header的名称 如:['姓名', '性别', '年龄']
  value: string[]; // list的数据key 如:['name', 'sex', 'age']
  list: Record<string, any>[]; // 数据源 如:[{name: '张三', sex: '男', age: 18}]
  fileName?: string;
  workbookName?: string;
}

/**
 * 导出excel文件-导出前记得先处理好后端返回的字段转成中文先
 * @param event
 */
export function handleExportExcel(event: HandleExportExcelType) {
  const data: Record<string, any>[] = [];
  const { header, list, value } = event;
  if (header.length !== value.length) {
    console.error('请确认header和value数组长度一致');
  } else if (list.length === 0) {
    ElMessage.warning('暂无数据!');
  } else {
    for (let index = 0; index < list.length; index++) {
      const element = list[index];
      const obj: Record<string, any> = {};
      for (let hIndex = 0; hIndex < header.length; hIndex++) {
        const hElement = header[hIndex];
        const data = value[hIndex]; // 长度一致所以可以直接使用header的index
        obj[hElement] = element[data];
      }
      data.push(obj);
    }
    const ws = XLSX.utils.json_to_sheet(data); // 新建空workbook,然后加入worksheet
    // ws['!cols'] = [{ wch: 10 }, { wch: 30 }, { wch: 25 }]; // 设置每列的列宽,10代表10个字符,注意中文占2个字符
    const wb = XLSX.utils.book_new(); // 新建book
    XLSX.utils.book_append_sheet(wb, ws, event.workbookName || '数据详情'); // 生成xlsx文件(book,sheet数据,sheet命名)
    XLSX.writeFile(wb, event.fileName || '导出.xlsx'); // 写文件(book,xlsx文件名称)
  }
}

axios下载文件功能,建立utils/down-file.ts

import axios from 'axios';
import { ElMessage } from 'element-plus';

/**
 * 导出后端生成url下载文件 如果该方案不适用则可以采用前端方案
 * @link https://blog.csdn.net/weixin_42246659/article/details/118936132?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164542407116781683996201%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164542407116781683996201&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-2-118936132.pc_search_result_positive&utm_term=vue3+xlsx&spm=1018.2226.3001.4187
 * @param data
 */
export function downloadExportFile(data: { url: string; params?: Record<string, any>; fileName?: string }): Promise<void> {
  // // 裁剪apiUrl最后一个/ 吧token添加上
  const apiUrl = data.url[0] === '/' ? data.url.substring(1) : data.url;
  const fileUrl = 'http://xxx.com/' + apiUrl;
  return new Promise((resolve) => {
    axios
      .get<Blob>(fileUrl, {
        params: data?.params,
        headers: {
          'token': 'token',
        },
        responseType: 'blob',
      })
      .then((res) => {
        if (res.status === 200) {
          console.log(res.data);
          const href = window.URL.createObjectURL(res.data); // 创建下载的链接
          // 获取响应头的文件命名 Content-Disposition: attachment;filename=xxx
          const fileName = data?.fileName || res.headers['content-disposition'].split('filename=')[1];
          createDownloadElement(href, decodeURIComponent(fileName));
          window.URL.revokeObjectURL(href); // 释放掉blob对象
        } else {
          ElMessage.error('导出异常!');
        }
        resolve();
      })
      .catch((error) => {
        console.error('导出失败!', error);
        ElMessage.error('导出失败!');
        resolve();
      });
  });
}

/**
 * 下载JSON
 * @param data
 * @param fileName
 */
export function downloadJSON(data: any, fileName: string) {
  const blob = new Blob([JSON.stringify(data)]);
  const href = window.URL.createObjectURL(blob); // 创建下载的链接
  createDownloadElement(href, `${fileName}-${new Date().getTime()}.json`);
  window.URL.revokeObjectURL(href); // 释放掉blob对象
}

/**
 * 创建a标签下载文件
 * @param url
 * @param name
 */
function createDownloadElement(url: string, name: string) {
  console.log(url, name);
  const downloadElement = document.createElement('a');
  downloadElement.href = url;
  downloadElement.download = name; // 下载后文件名
  document.body.appendChild(downloadElement);
  downloadElement.click(); // 点击下载
  document.body.removeChild(downloadElement); // 下载完成移除元素
}

vue3中使用

<template>
  <el-button @click="handleExport">导 出</el-button>
  <el-button @click="handleExportAxios">导 出</el-button>
</template>

<script lang="ts">
import { handleExportExcel } from '@/utils/excel';
import { downloadExportFile } from '@/utils/down-file';
import { defineComponent } from 'vue';
export default defineComponent({
  setup() {
    const handleExport = () => {
      handleExportExcel({
        header: ['姓名', '性别', '年龄'],
        value: ['name', 'sex', 'age'],
        list: [{ name: '张三', sex: '男', age: 18 }],
      });
    };
    const handleExportAxios = () => {
      	downloadExportFile({
	   		url: 'xxxx/xxx',
		    fileName: '下载.xlsx',
  		});
    };
    return {
      handleExport,
      handleExportAxios
    };
  },
});
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值