vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > el-table纯前端导出

如何使用el-table实现纯前端导出(适用于el-table任意表格)

作者:爱写代码的小奶龙

我们日常做项目,特别是后台管理系统,常常需要导出excel文件,这篇文章主要给大家介绍了关于如何使用el-table实现纯前端导出的相关资料,本文适用于el-table任意表格,需要的朋友可以参考下

今天我学习了如何使用el-table实现前端的导出功能,该方法的好处有无论你的el-table长什么样子,导出之后就是什么样子。

1.安装三个插件

npm install file-save
npm install xlsx
npm install xlsx-style

2.创建Export2Excel.js

// 根据dom导出表格
import { saveAs } from 'file-saver'
import * as XLSX from 'xlsx'
import * as XLSXStyle from "xlsx-style";

function s2ab(s) {
  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;
}

export function exportToExcel(idSelector, fileName, titleNum = 1) {
  // 设置导出的内容是否只做解析,不进行格式转换     false:要解析, true:不解析
  const xlsxParam = { raw: true }
  let table = document.querySelector(idSelector).cloneNode(true)
  // 因为element-ui的表格的fixed属性导致多出一个table,会下载重复内容,这里删除掉
  if (table.querySelector('.el-table__fixed-right')) {
    table.removeChild(table.querySelector('.el-table__fixed-right'))
  }
  if (table.querySelector('.el-table__fixed')) {
    table.removeChild(table.querySelector('.el-table__fixed'))
  }

  const wb = XLSX.utils.table_to_book(table, xlsxParam)
  let range = XLSX.utils.decode_range(wb.Sheets['Sheet1']['!ref'])
  let cWidth = []
  for (let C = range.s.c; C < range.e.c; ++C) {   //SHEET列
    let len = 100 //默认列宽
    let len_max = 400 //最大列宽
    for (let R = range.s.r; R <= range.e.r; ++R) {  //SHEET行
      let cell = { c: C, r: R }                    //二维 列行确定一个单元格
      let cell_ref = XLSX.utils.encode_cell(cell)  //单元格 A1、A2
      if (wb.Sheets['Sheet1'][cell_ref]) {
        // if (R == 0){
        if (R < titleNum) {
          wb.Sheets['Sheet1'][cell_ref].s = {  //设置第一行单元格的样式 style
            alignment: {
              horizontal: 'center',
              vertical: 'center'
            }
          }
        } else {
          wb.Sheets['Sheet1'][cell_ref].s = {
            alignment: {
              horizontal: 'center',
              vertical: 'center'
            }
          }
        }
        //动态自适应:计算列宽
        let va = JSON.parse(JSON.stringify(wb.Sheets['Sheet1'][cell_ref].v))
        var card1 = JSON.parse(JSON.stringify(va)).match(/[\u4e00-\u9fa5]/g) //匹配中文
        var card11 = ''
        if (card1) {
          card11 = card1.join('')
        }
        var card2 = JSON.parse(JSON.stringify(va)).replace(/([^\u0000-\u00FF])/g, '')  //剔除中文
        let st = 0
        if (card11) {
          // st += card11.length * 16  //中文字节码长度
          st += card11.length * 20  //中文字节码长度
        }
        if (card2) {
          // st += card2.length * 8  //非中文字节码长度
          st += card2.length * 10  //非中文字节码长度
        }
        if (st > len) {
          len = st
        }
      }
    }
    if (len > len_max) {//最大宽度
      len = len_max
    }

    cWidth.push({ 'wpx': len })     //列宽
  }
  wb.Sheets['Sheet1']['!cols'] = cWidth
  const wbout = XLSXStyle.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' })
  try {
    saveAs(new Blob([s2ab(wbout)], { type: '' }), `${fileName}.xlsx`)
  } catch (e) {
    if (typeof console !== 'undefined') {
      console.log(e, wbout)
    }
  }
  return wbout
}

3.按需引入

<template>
    <div>
      <el-table  id='table'>
        //形式一
        <el-table-column>
         <template>
           <span>可以用插槽形式</span>
         </template>
        </el-table-column>
     
        //形式二
        <el-table-column lable=可以用这种形式' prop='xxx'/>
     
        //形式三(不可用)
        <el-table-column>
          <template>
            <el-input  v-model=''/>//该方式无法识别到
          </template>
        </el-table-column>

     </el-table>//给表格一个id
      <el-button @click='demo'>导出</el-button>
    </div>
</template>

<script>
import { exportToExcel } from '@/Export2Excel'

export default{
  data(){
    return{}
 },
  methods:{
      demo(){
        exportToExcel('#table', '导出名称')//id选择器,导出名称,调用这个方法就可以了
      }
  }
}
</script>

4.vue.config.js引入

  //在这个方法里面
  configureWebpack: {
    name: name,
    resolve: {
      alias: {
        '@': resolve('src')
      }
    },
    plugins: [
      // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
      new CompressionPlugin({
        cache: false,                   // 不启用文件缓存
        test: /\.(js|css|html)?$/i,     // 压缩文件格式
        filename: '[path].gz[query]',   // 压缩后的文件名
        algorithm: 'gzip',              // 使用gzip压缩
        minRatio: 0.8                   // 压缩率小于1才会压缩
      })
    ],


    //加入这三行
    externals: [{
      './cptable': 'var cptable'
    }]



  },

效果:

扩展:

当我们会出现这样的表格需求时,如果只是用v-if判断,导出来会全部也有,因为我们只做了v-if的判断

实现代码如下:

<span v-if="index===0">{{scope.row.xxxx}}</span>//如果是第一行就显示值
<span v-else></span>//如果不是就为空

这样就可以防止只需要第一个行数据的时候其他还会显示的问题。

总结

到此这篇关于如何使用el-table实现纯前端导出的文章就介绍到这了,更多相关el-table纯前端导出内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文