当前位置:首页 » 《资源分享》 » 正文

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

19 人参与  2024年04月15日 18:51  分类 : 《资源分享》  评论

点击全文阅读


2023.9.1今天我学习了如何使用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>//如果不是就为空

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


点击全文阅读


本文链接:http://zhangshiyu.com/post/95780.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1