vue 实现Excel导出文件,设置单元格样式,居中,靠右,边框等,并设置数据类型货币类型, 使用xlsx,xlsx-style插件实现

1、 下载插件 xlsx xlsx-style

npm install --save xlsx xlsx-style

2、 进行数据导出

根据 自己业务更改表格样式及导出数据类型

import XLSX from 'xlsx'
import * as XLSXStyle from 'xlsx-style';
export default {
  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;
  },
// 根据dom导出表格
//idSelector 界面中的需要导出的DOMid, fileName导出的文件名称
  exportToExcel(idSelector, fileName) {
    // 设置导出的内容是否只做解析,不进行格式转换     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]) {
        //设置单元格样式 从第4列,第2行开始设置,向右靠齐,增加边框
          if (cell.c > 3 && cell.r > 1) {
          	//设置导出的数值为number类型 ,number类型导出在Excel文件中可进行累加等函数操作,String类型择不可以
            wb.Sheets['Sheet1'][cell_ref].t = 'n' // t为设置的类型 布尔值为b n 为number类型 s 为string类型
            // 指定哪一列的样式
            wb.Sheets['Sheet1'][cell_ref].s = { //s 是设置样式
              alignment: {
                horizontal: 'right',
                vertical: 'center',
              },
              border: {
                top: { style: 'thin' },
                bottom: { style: 'thin' },
                left: { style: 'thin' },
                right: { style: 'thin' }
              }
            };
            //其余单元格样式
          } else {
            wb.Sheets['Sheet1'][cell_ref].s = {
              alignment: {
                horizontal: 'center',
                vertical: 'center',
              },
              border: {
                top: { style: 'thin' },
                bottom: { style: 'thin' },
                left: { style: 'thin' },
                right: { style: 'thin' }
              }
            };
          }
          // 在这里设置数字格式数据为货币类型
          if (wb.Sheets['Sheet1'][cell_ref].t === 'n') {
          	//从界面获取节点后拿到的数据 我的数据是string类型 ,可以自己console一下看看数据类型是是什么
            if(typeof wb.Sheets['Sheet1'][cell_ref].v === 'string'){
              //将有千分位的数据去掉千分位
              wb.Sheets['Sheet1'][cell_ref].v = wb.Sheets['Sheet1'][cell_ref].v.replace(/,/g,"")
              let value = parseFloat(wb.Sheets['Sheet1'][cell_ref].v);
              if (!isNaN(value)) {
                wb.Sheets['Sheet1'][cell_ref].z = '#,##0.00'; // 设置单元格的类型 为货币类型
              }
            }
          }
          //动态自适应:计算列宽
          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 * 20  //中文字节码长度
          }
          if (card2) {
            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
    // binary
    const wbout = XLSXStyle.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' })
    try {
      saveAs(new Blob([this.s2ab(wbout)], { type: 'application/octet-stream' }), `${fileName}.xlsx`)
      // FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${fileName}.xlsx`);
    } catch (e) {
      if (typeof console !== 'undefined') {
        console.log(e, wbout)
      }
    }
    return wbout
  }
 }

3、 使用函数

 <!-- #'#out-table'为id ,后面的参数为导出报表的名称-->
<el-button type="warning" @click="$exportFn.exportToExcel('#out-table','联营租赁营业款日报表')" size="small">导出</el-button>

<script>
import XLSX from 'xlsx';
import $exportFn from '@/components/exportFn'
</script> 

你可能感兴趣的:(vue.js,excel,前端)