vue前端开发导出excel表格文字版本以及含图片版本

文章介绍了在Vue项目中导出Excel的几种方法,包括使用xlsxfile-saver和file-saver库的简单方法,处理固定列问题,以及针对不同浏览器(尤其是IE)的兼容性处理。另外,还提到了excel.js库用于设置样式和处理复杂表格的导出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.文字版本

这个办法是最简易的方法 我是配合element使用的
下载依赖包 xlsx file-saver

npm install xlsx file-saver --save

倒没有封装工具类 毕竟这个方法比较简单 直接上就行
在需要导出excel表格的页面引入

import FileSaver from 'file-saver'
import * as XLSX from 'xlsx'
//在methods里面写一个点击事件click  名字自己写
//PopBo 是固定某一列的,因为这个导出如果固定列了  会打印两遍 
//所以我在固定列那里做了一个v-if判断
//还有需要注意的是需要在<el-table id="exportTab"> 加上id="exportTab"
click(){
      this.PopBo = false
      // this.getList() // 这个是重新2加载表格,意思是每次点击导出的时候都要重新加载一次表格以确定是否在导出前新增了表格内的数据
      // settimeout:延迟加载 如果不延迟一点加载则会出现导出的数据不是最新的。
      var xlsxParam = { raw: true } // 导出的内容只做解析,不进行格式转换
      setTimeout(() => {
        /* 从表生成excel工作簿对象 */
        let wb
        let fix
        // 判断固定在左边还有右边  获取相应的dom
        if (this.operateFixed === 'right') {
          fix = document.querySelector('.el-table__fixed-right')
        } else if (this.operateFixed === 'left') {
          fix = document.querySelector('.el-table__fixed')
        }
        // 判断是否固定了操作栏
        // 如果固定了会出现打印两次的bug 需要暂时移除fix固定打印
        if (fix) {
          wb = XLSX.utils.table_to_book(
            document.querySelector('#exportTab').removeChild(fix), xlsxParam
          )
          document.querySelector('#exportTab').appendChild(fix)
        } else {
          wb = XLSX.utils.table_to_book(document.querySelector('#exportTab'), xlsxParam)
        }

        /* 获取二进制字符串作为输出 */
        var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
        try {
          FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream;charset=utf-8' }), '我的客诉单列表.xlsx')
        } catch (e) {
          if (typeof console !== 'undefined') {
            console.log(e, wbout)
          }
        }
        this.PopBo = true
      }, 0)
      // return wbout
}

第一种方法大概就是这样
我做了固定的列的处理 如果不需要 觉得冗余可以按需删除

1.文字含图片版本

这个导出方法直接引用就可以了,缺点就是导出的excel格式是xls而不是xlsx,然后打开会有个提示,点是即可,几乎没啥区别,进入话题

首先创建一个export2Excel.js文件

// 复制代码粘贴即可
let idTmr
const getExplorer = () => {
  let explorer = window.navigator.userAgent
  //ie
  if (explorer.indexOf('MSIE') >= 0) {
    return 'ie'
  }
  //firefox
  else if (explorer.indexOf('Firefox') >= 0) {
    return 'Firefox'
  }
  //Chrome
  else if (explorer.indexOf('Chrome') >= 0) {
    return 'Chrome'
  }
  //Opera
  else if (explorer.indexOf('Opera') >= 0) {
    return 'Opera'
  }
  //Safari
  else if (explorer.indexOf('Safari') >= 0) {
    return 'Safari'
  }
}
// 判断浏览器是否为IE
const exportToExcel = (data, name) => {
  // 判断是否为IE
  if (getExplorer() == 'ie') {
    tableToIE(data, name)
  } else {
    tableToNotIE(data, name)
  }
}

const Cleanup = () => {
  window.clearInterval(idTmr)
}

// ie浏览器下执行
const tableToIE = (data, name) => {
  let curTbl = data
  let oXL = new ActiveXObject('Excel.Application')

  //创建AX对象excel
  let oWB = oXL.Workbooks.Add()
  //获取workbook对象
  let xlsheet = oWB.Worksheets(1)
  //激活当前sheet
  let sel = document.body.createTextRange()
  sel.moveToElementText(curTbl)
  //把表格中的内容移到TextRange中
  sel.select
  //全选TextRange中内容
  sel.execCommand('Copy')
  //复制TextRange中内容
  xlsheet.Paste()
  //粘贴到活动的EXCEL中

  oXL.Visible = true
  //设置excel可见属性

  try {
    let fname = oXL.Application.GetSaveAsFilename(
      'Excel.xls',
      'Excel Spreadsheets (*.xls), *.xls'
    )
  } catch (e) {
    print('Nested catch caught ' + e)
  } finally {
    oWB.SaveAs(fname)

    oWB.Close((savechanges = false))
    //xls.visible = false;
    oXL.Quit()
    oXL = null
    // 结束excel进程,退出完成
    window.setInterval('Cleanup();', 1)
    idTmr = window.setInterval('Cleanup();', 1)
  }
}

// 非ie浏览器下执行
const tableToNotIE = (function () {
  // 编码要用utf-8不然默认gbk会出现中文乱码
  let uri = 'data:application/vnd.ms-excel;base64,',
    template =
      '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta charset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>',
    base64 = function (s) {
      return window.btoa(unescape(encodeURIComponent(s)))
    },
    format = (s, c) => {
      return s.replace(/{(\w+)}/g, (m, p) => {
        return c[p]
      })
    }
  return (table, name) => {
    let ctx = {
      worksheet: name,
      table
    }

    //创建下载
    let link = document.createElement('a')
    link.setAttribute('href', uri + base64(format(template, ctx)))

    link.setAttribute('download', name)

    // window.location.href = uri + base64(format(template, ctx))
    link.click()
  }
})()

export default exportToExcel

然后在需要导出的页面引入js文件

import exportToExcel from '文件地址'

数据表头数组和tabody数组按顺序排序好
在methods下封装这个函数

	 //exportExcel(theadData,tbodyData,name)
	 //exportExcel 函数里面有 5 个参数其中有三个参数是必填
	 //theadData 是表头展示数据 ,(必填) 类型是 Array
	 //tbodyData 是表格展示的数据,(必填)类型是 Array
	 //name 是导出文件的名字 (必填)String
    export2Excel(theadData, tbodyData, dataname) {
     let re = /http/; // 字符串中包含http,则默认为图片地址
     let th_len = theadData.length; // 表头的长度
     let tb_len = tbodyData.length; // 记录条数
     let width = 120; // 设置图片大小
     let height = 80;

     // 添加表头信息
     let thead = "<thead><tr>";
     for (let i = 0; i < th_len; i++) {
       thead += "<th>" + theadData[i] + "</th>";
     }
     thead += "</tr></thead>";

     // 添加每一行数据
     let tbody = "<tbody>";
     for (let i = 0; i < tb_len; i++) {
       tbody += "<tr>";
       let row = tbodyData[i]; // 获取每一行数据

       for (let key in row) {
         if (re.test(row[key])) {
           // 如果为图片,则需要加div包住图片
           //
           tbody +=
             '<td style="width:' +
             width +
             "px; height:" +
             height +
             'px; text-align: center; vertical-align: middle"><div style="display:inline"><img src=\'' +
             row[key] +
             "' " +
             " " +
             "width=" +
             '"' +
             width +
             '"' +
             " " +
             "height=" +
             '"' +
             height +
             '"' +
             "></div></td>";
         } else {
           tbody += '<td style="text-align:center">' + row[key] + "</td>";
         }
       }
       tbody += "</tr>";
     }
     tbody += "</tbody>";

     let table = thead + tbody;

     // 导出表格
     exportToExcel(table, dataname);
   }

点击导出的时候调用并传递参数

    // 导出表格
    exportTable() {
    //假数据  用以参考
	  const tHeader = ['序号','名字','年龄']
	  const tbody = [{num:1,name:'小明',age:18},{num:2,name:'小6',age:19},{num:3,name:'小7',age:20}]
      this.export2Excel(tHeader, tbody, '名字随便取')
    },

这个版本参考了一个大佬 此处

这些都是直接赋值粘贴使用即可
温馨提示 哈哈
如果需要用到合并,复杂表格,我就是复杂表格 很多复杂的
可以考虑在td 那里添加rowspan的数量来实现合并的需求

3.文字图片版本第二版本

这个版本老实说不怎么推荐 不是说不能用 是如果导出图片需要转base64 需要后端处理跨域

用excel.js 或者 as-xlsx.js
可以参考官网excel.js中文版文档 点击此处即可跳转

4.纯文字还可以用excel.js 设置样式简单

同样的先下包

npm install exceljs

在需要的页面导出包

const ExcelJS = require('exceljs');

因为官方文档已经很详细了,我就只弄导出excel.js需要哪些部分

    exportStyledTable(tBody) {
      /* 从表生成excel工作簿对象 */
      const workbook = new ExcelJS.Workbook()
      workbook.creator = 'Me'
      workbook.lastModifiedBy = 'Me'
      workbook.created = new Date()
      workbook.modified = new Date()

	  /* 添加工作表  这个就是excel表格下面的分批工作表的名字*/
      const worksheet = workbook.addWorksheet('自定义 中英文都可以')

	  /* 添加表头  这里的key对应数据里面的键值对 */
      worksheet.columns = [
        { header: '序号', key: 'rowNumber', width: 5 },
        { header: '姓名', key: 'name', width: 15 },
        { header: '年龄', key: 'age', width: 10 },
      ]

	  /* 添加数据 */
      const data = [
      {rowNumber:1,name:'小明',age:18},
      {rowNumber:2,name:'小红',age:19},
      {rowNumber:3,name:'小蓝',age:20},
      ]

	   // 添加每一行数据
      data.forEach(item => {
        worksheet.addRow(item).commit()
      })

	  /* 格式化单元格  如果不需要这些样式 可以删除*/
      worksheet.eachRow((row, rowNumber) => {
        row.eachCell(cell => {
          cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true } //所有内容居中显示
        })
        // 第一行就是表头
        if (rowNumber === 1) {
          row.eachCell(cell => {
            cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: '9dc3e6' }} // 设置表头背景色
            cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' }, color: { argb: 'c3cbdd' }} // 给背景色覆盖的边框添加边框
            cell.font = { bold: true } // 字体加粗
          })
        }
      })
      // 删除到这里就可以了

	       /* 导出 Excel 文件 */
      workbook.xlsx.writeBuffer().then(buffer => {
        try {
          const file = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
          FileSaver.saveAs(file, '导出文件名.xlsx')
        } catch (e) {
          // console.error(e)
        }
      })
      
    }

这个方法也有处理合并,我也用这个方法处理过合并,难度不大。

码字不易 如果有用,希望路过随手点赞点收藏 谢谢

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值