基于el-table的树形表格及js-xlsx实现下载excel功能(二)


这篇主要是利用xlsx下载表格,网上参考的资料挺多的

一、安装xlsx

xlsx npm

我用到的也就前三个
在这里插入图片描述
就最简单的使用来说:

aoa_to_sheet 就是把一个数组arr塞到一个sheet页中,arr类似于这种结构

arr = [
	['姓名', '年龄', '性别'],
	['张三', '18', '男'],
	['李四', '23', '女'],
]

json_to_sheet 的json数据长下面这样, 它会自动将键值变成表头,注意键值不能重复

arr = [
	{'姓名': '张三', '年龄': '18', '性别': '男'},
	{'姓名': '李四', '年龄': '23', '性别': '女'}
]

table_to_sheet 的最简单,你页面就显示了这么个表格,直接获取dom,再将这个dom作为参数就行了 。
最终下载的excel都是下面这样
在这里插入图片描述

二、下载的表出现科学计数法

当数据较长,超过了10位时, excel打开显示的是科学计数。 主要原因是单元格将其看做数值处理,网上有解决办法是给td加 style="mso-number-format:'\@';", 但似乎没有用,看xlsx文档,发现将raw设置为true, 即将其看做字符串处理

raw: If true, every cell will hold raw strings

 // raw为true的作用是把数字当成string
 var sheet = XLSX.utils.table_to_sheet(objE.childNodes[0], { raw: true })
三、代码
设置excel样式

xlsx 目前更改的样式有限,只能设置列宽,合并单元格等,更复杂的样式修改可以看看xlsx-style


setExcelStyle() {
   const obj = {}
   const colsNum = this.cmpColumns.length
   // 动态添加列宽
   for(let i = 0; i < colsNum; i++){
     obj['!cols'].push({ wch: 15 })
   }
	/** 合并单元格 - 合并第一列的一二行
	obj['!merges'] = [{
          s: {  // 开始
            c: 0,
            r: 0,   // 0 行
          },
          e: { // 结束
            c: 0,
            r: 1,  // 1行
          },
        }]
   */
	
   return obj
 },
写成工具函数
/*
 * 工具函数
 * @FilePath: assets\js\excel.js
 */
import XLSX from 'xlsx'

function s2ab(s) {
  if (typeof ArrayBuffer !== 'undefined') {
    var buf = new ArrayBuffer(s.length)
    var view = new Uint8Array(buf)
    for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
    return buf
  } else {
    var buf = new Array(s.length);
    for (var i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
    return buf;
  }
}

function type2Excel({data, style, type = "json", header = [], skipHeader = false}) {
  
  //1、XLSX.utils.json_to_sheet(data) 接收一个对象数组并返回一个基于对象关键字自动生成的“标题”的工作表,默认的列顺序由使用Object.keys的字段的第一次出现确定
  //2、将数据放入对象workBook的Sheets中等待输出
  let sheet = null
  switch (type) {
    case 'json':
      sheet = Object.assign(XLSX.utils.json_to_sheet(data, {header, skipHeader}), style)
      break
    case 'aoa':
      sheet = Object.assign(XLSX.utils.aoa_to_sheet(data), style)
      break
    case 'dom':
      sheet = Object.assign(XLSX.utils.table_to_sheet(data, { raw: true }), style)
      break
    default:
      break
  }
  return sheet
}

/**
 * @description: 传入一个数组,数组对象内容为 sheetName, data, style, type = "json", header = {}, skipHeader = true
 * @param {*} sheets
 * @return {*}
 */
function genExcel(sheets){
  var wopts = {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  };
  var workBook = {
    SheetNames: [],
    Sheets: {},
    Props: {}
  };
  
  for(let sheet of sheets){
    const name = sheet.sheetName
    workBook.SheetNames.push(name)
    workBook.Sheets[name] = type2Excel(sheet)
  }

  //3、XLSX.write() 开始编写Excel表格 , s2ab() 将数据处理成需要输出的格式
  const blob = new Blob([s2ab(XLSX.write(workBook, wopts))], {
    type: 'application/octet-stream'
  })
  return blob
}

export {
  s2ab,
  type2Excel,
  genExcel
}
模拟a标签,点击下载函数
/*
 * @Description: post方式的接口,或者前端下载使用
 * @FilePath: assets\js\PostDLFile.js
 */
export default function postDLFile(data, name) {
  let blob = data
  let reader = new FileReader()
  reader.readAsDataURL(blob)
  reader.onload = (e) => {
    let a = document.createElement('a')
    a.download = `${name}.xlsx`
    a.href = e.target.result
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
  }
}
下载使用
downloadOrg(){
  // 这个函数就是你自己处理数据的函数,数据长啥样调啥样的接口
  const data = this.genJsonForExcel()  
  
  const style = this.setExcelStyle()
  const sheets = [{sheetName:'机构数据', data, style, 'json'}]
  postDLFile(genExcel(sheets), '下载的excel名字')
},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值