前端导出excel格式文件

前段时间做了个前端导出的功能,自定义导出文件名。把思路和代码分享下,希望对大家有所帮助。

需求:导出页面列表展示的所有数据。
思路:

  1. 数据量大了,让后端生成excel二进制文件流,前端拿流直接下载;
  2. 后端不生成,那么轮询调接口返回数据,页面做个等待的进度条,进度条提示语显示已获取条数据/共条数据;获取到所有数据后处理获取数据的格式,使用js-xlsx 下载excel格式文件。

资源下载

通过浏览器地址栏访问下面地址 https://unpkg.com/[email protected]/dist/xlsx.full.min.js,得到的js保存到本地,index.html中引入;如果项目中引入了ts,会报错找不到名称“XLSX,解决办法可参考一下链接 。

如果地址失效了,在github上下载,附链接 https://github.com/SheetJS/sheetjs;最后,要是github上下载不了,可以上我的仓库里拉取代码,附仓库链接https://gitee.com/wanglun945/wl-easy-ui

实现需求

  • 思路1 — 后端下载
    使用XMLHttpRequest异步请求对象,通过setRequestHeader设置请求类型,接口校验token等信息,使用FileReader读取请求回来的二进制流转换成的Blob对象,读取成功后使用URL.createObjectURL转成base64 url链接,最后使用a标签下载;
    注:可以通过响应头Content-disposition属性配置动态生成下载excel的文件名
function updownFileExcel (method: string, url: string, queryParams) {
    var xhr = new XMLHttpRequest();
    xhr.open(method, url,  true);
    xhr.responseType = 'blob';
    xhr.setRequestHeader("token", "*****");
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onload = function(e) {
        var blob = new Blob([this.response], {type: 'application/octet-stream'});
        var fileReader: FileReader = new FileReader();
        fileReader.onload = function() {
          try {
            var r = JSON.parse(fileReader.result as string);
            var message = r.message, flag = r.flag;
            flag == "0" && Message.error({content: message, duration: 3});
          } catch (e) {
            var href = URL.createObjectURL(blob);
            var fileName = xhr.getResponseHeader('Content-disposition');
            var elink = document.createElement('a');
            elink.download = fileName ? decodeURI(fileName.split('=')[1].replace(/"/g, '')) : '';
            elink.style.display = 'none';
            elink.href = href;
            document.body.appendChild(elink);
            elink.click();
            URL.revokeObjectURL(elink.href);
            document.body.removeChild(elink);
          }
        }
        fileReader.readAsText(blob);
    };
    xhr.onerror = function (e) {
        Message.error({content:'网络异常,请稍后再试!', duration: 3});
    }
    xhr.send(JSON.stringify(queryParams));
  }
  • 思路2 — 前端下载

在index.html中引入xlsx.full.min.js后,使用 ExportExcel类,传入三个参数,分别是导出的数据,excel表格文件名,excel文件文件名。data数据类型格式要求 string[][]。

export default class ExportExcel {
  data: string[][];
  sheetNames: string[];
  excelName: string;
  constructor (data: string[][], sheetNames: string[], excelName: string) {
    this.data = data;
    this.sheetNames = sheetNames;
    this.excelName = excelName;
  }
  getSheetsData () {
    let sheets = [XLSX.utils.aoa_to_sheet(this.data)];
    let blob = this.sheet2blob(sheets, this.sheetNames);
    this.updownExcel(blob, this.excelName + ".xlsx");
  }
  sheet2blob (sheet, sheetName): Blob {
    let workbook = {
      SheetNames: sheetName,
      Sheets: {}
    };
    sheetName.forEach((n, i) => {
      workbook.Sheets[n] = sheet[i]
    })
    let wbout = XLSX.write(workbook, {bookType: 'xlsx', bookSST: false, type: 'binary'});
    let blob = new Blob([this.toBuffer(wbout)], {type: 'application/octet-stream'});
    return blob
  }
  toBuffer (s): ArrayBuffer {
    let buf = new ArrayBuffer(s.length);
    let view = new Uint8Array(buf);
    for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
    return buf
  }
  updownExcel (blob, fileName) {
    const aLink = document.createElement('a');
    aLink.download = fileName;
    aLink.style.display = 'none';
    aLink.href = URL.createObjectURL(blob);
    document.body.appendChild(aLink);
    aLink.click();
    URL.revokeObjectURL(aLink.href);
    document.body.removeChild(aLink);
  }
}

使用demo:

import { defineComponent } from "vue";
import ExportExcel from "./ts/exportExcel"
import { Button } from 'view-ui-plus';

export default defineComponent({
  setup() {
    let data = [
      ["标题1", "标题2", "标题3"],
      ["1-a", "2-a", "3-a"],
      ["1-b", "2-b", "3-b"]
    ];
    let excel = new ExportExcel(data, ["sheet表名"], "excel名称");
    return () => (
      <>
        <Button onClick={() => excel.getSheetsData()}>导出</Button>
      </>
    )
  }
})

前端导出excel格式文件_第1张图片

你可能感兴趣的:(vue,前端,excel,javascript)