vue 下载xlsx或xls表格

93 篇文章 1 订阅
267 篇文章 3 订阅

需求:

后台没有提供下载接口,就只能下载插件调用查询接口,把查询出来的数据通过插件生成xlsx或xls表格导出来

对应插件:

npm install --save xlsx-style

npm install file-saver --save

创建一个文件export2Excel.js

/* eslint-disable */
import { saveAs } from 'file-saver'
import XLSX from 'xlsx-style'

function dataNum(v, date1904) {
  if (date1904) v += 1462
  const epoch = Date.parse(v)
  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000)
}

function sheetFromArrayOfArrays(headers, data) {
  const ws = {}
  const range = {
    s: {
      c: 10000000,
      r: 10000000
    },
    e: {
      c: 0,
      r: 0
    }
  }
  /*设置worksheet每列的最大宽度*/
  for (let R = 0; R !== headers.length; ++R) {
    for (let C = 0; C !== headers[R].length; ++C) {
      if (range.s.r > R) range.s.r = R
      if (range.s.c > C) range.s.c = C
      if (range.e.r < R) range.e.r = R
      if (range.e.c < C) range.e.c = C
      const cell = {
        v: headers[R][C]
      }
      if (cell.v == null) continue
      const cell_ref = XLSX.utils.encode_cell({
        c: C,
        r: R
      })

      if (typeof cell.v === 'number') {
        cell.t = 'n'
      } else if (typeof cell.v === 'boolean') {
        cell.t = 'b'
      } else if (cell.v instanceof Date) {
        cell.t = 'n'
        cell.z = XLSX.SSF._table[14]
        cell.v = dataNum(cell.v)
      } else {
        cell.t = 's'
      }
      cell.s = {
        border:{
          top: {
            style: 'thin'
          },
          bottom: {
            style: 'thin'
          },
          left: {
            style: 'thin'
          },
          right: {
            style: 'thin'
          }
        },
        fill: {
          fgColor: {rgb: 'CDCDCD'},
        },
        font: {
          bold: true
        },
        alignment: {
          horizontal: 'center',
          vertical: 'center'
        }
      }
      ws[cell_ref] = cell
    }
  }
  for (let R = headers.length; R !== data.length + headers.length; ++R) {
    for (let C = 0; C !== data[R - headers.length].length; ++C) {
      if (range.s.r > R) range.s.r = R
      if (range.s.c > C) range.s.c = C
      if (range.e.r < R) range.e.r = R
      if (range.e.c < C) range.e.c = C
      const cell = {
        v: data[R - headers.length][C]
      }
      if (cell.v == null) continue
      const cell_ref = XLSX.utils.encode_cell({
        c: C,
        r: R
      })

      if (typeof cell.v === 'number') {
        cell.t = 'n'
      } else if (typeof cell.v === 'boolean') {
        cell.t = 'b'
      } else if (cell.v instanceof Date) {
        cell.t = 'n'
        cell.z = XLSX.SSF._table[14]
        cell.v = dataNum(cell.v)
      } else {
        cell.t = 's'
      }
      cell.s = {
        border: {
          top: {
            style: 'thin'
          },
          bottom: {
            style: 'thin'
          },
          left: {
            style: 'thin'
          },
          right: {
            style: 'thin'
          }
        },
        alignment: {
          vertical: 'center'
        }
      }
      ws[cell_ref] = cell
    }
  }
  if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range)
  return ws
}

function Workbook() {
  if (!(this instanceof Workbook)) return new Workbook()
  this.SheetNames = []
  this.Sheets = {}
}

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
}

export function sheetMaker({
                             headers = [],
                             data,
                             merges = [],
                             autoWidth = true
                           } = {}) {
  data = [...data]
  if (!headers.every(header => header instanceof Array)) {
    headers = [headers]
  }
  const ws = sheetFromArrayOfArrays(headers, data)
  if (merges.length > 0) {
    if (!ws['!merges']) ws['!merges'] = []
    merges.forEach(item => {
      ws['!merges'].push(XLSX.utils.decode_range(item))
    })
  }

  if (autoWidth) {
    /*设置worksheet每列的最大宽度*/
    if (headers.every(header => header instanceof Array)) {
      for (let i = headers.length - 1; i > -1; i--) {
        data.unshift(headers[i])
      }
    } else {
      data.unshift(headers)
    }
    const colWidth = data.map(row => row.map(val => {
      /*先判断是否为null/undefined*/
      if (val == null) {
        return {
          'wch': 10
        }
      }
      /*再判断是否为中文*/
      else if (val.toString().charCodeAt(0) > 255) {
        return {
          'wch': val.toString().length * 2 > 150 ? 150 : val.toString().length * 2
        }
      } else {
        return {
          'wch': val.toString().length > 150 ? 150 : val.toString().length
        }
      }
    }))
    /*以Header最后一行为初始值*/
    let result = colWidth[headers.length - 1]
    for (let i = 1; i < colWidth.length; i++) {
      for (let j = 0; j < colWidth[i].length; j++) {
        if (result[j]['wch'] < colWidth[i][j]['wch']) {
          result[j]['wch'] = colWidth[i][j]['wch']
        }
      }
    }
    ws['!cols'] = result
  }
  return ws
}

export function json2Excel({ headers, data, keys, filter, sheetName = 'Sheet 1', fileName = 'excel-list', merges = [], autoWidth = true, bookType = 'xlsx' }) {
  // 数据处理
  data = data.map(item => keys.map(key => {
    if (filter && filter instanceof Function) {
      const value = filter(key, item[key], item)
      return value == null ? item[key] || '' : value
    } else {
      return item[key] == null ? '' : item[key]
    }
  }))
  data = [...data]
  // 表格对象
  const wb = new Workbook()
  const ws = sheetMaker({ headers, data, merges, autoWidth })
  wb.SheetNames.push(sheetName)
  wb.Sheets[sheetName] = ws
  const wbout = XLSX.write(wb, {
    bookType: bookType,
    bookSST: false,
    type: 'binary'
  })

  saveAs(new Blob([s2ab(wbout)], {
    type: 'application/octet-stream'
  }), `${fileName}.${bookType}`)
}

页面使用:

html:

  <el-button
          :disabled="!params.PAYDETFINDINFO.PAYPLANNO"
          class="sale-button-addon sale-icon-download"
          type="primary"
          round
          plain
          @click="clickExportSeatBtn"
        >导出
        </el-button>

 methods:

import { json2Excel } from '@/utils/export2Excel'

//js mothds


  // 导出
      clickExportSeatBtn() {
        if (+this.totalCount > 1000) {
          this.$message.warning('每次最多导出1000条数据')
        }
        const exportFilter = (key, keyValue, item) => {
          if (key === 'userCode') {
            return item.groupUserCode || item.userCode
          }
          if (key === 'landFlag') {
            return keyValue || '0'
          }
        }
        const fileName = parseTime(new Date(), '{y}{m}{d}{h}{i}{s}')
        const exportFn = (list) => {
          json2Excel({
            data: list,
            keys: ['seatCode', 'userCode', 'lastLogonTime', 'insertTimeForHis'],
            headers: [
              ['坐席编码', '用户代码',  '最后一次登录时间', '插入时间']
            ],
            merges: [],
            filter: exportFilter,
            fileName: 'SeatMain' + fileName.toString()
          })
        }
        const exportParams = {
          'currPage': 1,
          'pageSize': 1000,
          'currUserCode': this.$store.state.user.info.userCode,
          
        }
//调用查询接口
        seatMainFindSeatMainByPage(exportParams).then(res => {
          exportFn(res.result instanceof Array ? res.result : [res.result])
        }).catch(err => {
          this.$message.error(err)
        })
      },

 

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周家大小姐.

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值