纯前端的导出(vue)

1,873 阅读3分钟

1、单表头的导出

微信图片_20220110140515.png

(1)引入vuei-json-excel的依赖

npm i vue-json-excel -D

(2)全局注册或局部注册

  • 全局注册(main.js)
import JsonExcel from 'vue-json-excel'
Vue.component('downloadExcel', JsonExcel)
  • 局部注册
import downloadExcel from 'vue-json-excel'

就可以在页面中进行使用

<download-excel
  class="export-excel-wrapper"
  :data="echartData"
  :fields="excelHead"
  name="导出的文件名.xls'"
>
  <!-- 上面可以自定义自己的样式,还可以引用其他组件button -->
  <el-button type="primary" size="small" class="deriveBtn">导出</el-button>
</download-excel>
echartData: [] //table的数据
excelHead: [] //table的对应的字段

比如:

//前面是表头,后面对应的是字段
excelHead: [ 
    {
        "名字": "name",
        "年龄": "age"
    }
]

在导出的时候,会遇到的问题,接口返回的是id,但是导出的excel中需要展示的是对应的名称,不要怕我们也有方法进行解决:

比如:返回的性别是0或者10表示男,1表示女。

excelHead: [ 
    {
        "名字": "name",
        "年龄": "age",
        "性别": {
              field: 'sex', // 对应的字段
              callback: value => { //进行数据处理
                return value === 0 ? "男" : "女"
              }
        }
    }
]

这样我们就可以实现简单的excel导出啦!

2、多表头的导出

微信图片_20220110145356.png

(1)这里需要引入两个依赖file-saver -D和yxg-xlsx-style

npm i yxg-xlsx-style -D
npm i file-saver -D

引入成功之后,可以在

>src
  >util
    exportExcel.js

创建一个js文件:

注册file-saver和yxg-xlsx-style

import { saveAs } from 'file-saver'
import XLSX from 'yxg-xlsx-style'
export function export_json_to_excel({
    multiHeader = [],
    header,
    data,
    filename,
    merges = [],
    setStyleCallBack,
    autoWidth = true,
    bookType = 'xlsx'
  } = {}) {
    /* original data */
    filename = filename || 'excel-list'
    data = [...data]
    data.unshift(header);
  
    for (let i = multiHeader.length - 1; i > -1; i--) {
      data.unshift(multiHeader[i])
    }
    var ws_name = "SheetJS";
    var wb = new Workbook(),
      ws = sheet_from_array_of_arrays(data);
  
    if (merges.length > 0) {
      if (!ws['!merges']) ws['!merges'] = [];
      merges.forEach(item => {
        ws['!merges'].push(XLSX.utils.decode_range(item))
      })
    }
  
    if (autoWidth) {
      /*设置worksheet每列的最大宽度*/
      const colWidth = data.map(row => row.map(val => {
        /*先判断是否为null/undefined*/
        if (val == null) {
          return {
            'wch': 10
          };
        }
        /*再判断是否为中文*/
        else if (val.toString().charCodeAt(0) > 255) {
          return {
            'wch': val.toString().length * 2
          };
        } else {
          return {
            'wch': val.toString().length
          };
        }
      }))
      /*以第一行为初始值*/
      let result = colWidth[0];
      for (let i = 1; i < colWidth.length; i++) {
        for (let j = 0; j < colWidth[i].length; j++) {
          if (result[j]['wch'] < colWidth[i][j]['wch']) {
            result[j]['wch'] = colWidth[i][j]['wch'];
          }
        }
      }
      ws['!cols'] = result;
    }
  
    /* add worksheet to workbook */
    wb.SheetNames.push(ws_name);
    wb.Sheets[ws_name] = ws;
    var dataInfo = wb.Sheets[wb.SheetNames[0]];
    // 设置样式
    setStyleCallBack&&setStyleCallBack(dataInfo)

    var wbout = XLSX.write(wb, {
      bookType: bookType,
      bookSST: false,
      type: 'binary'
    });
    saveAs(new Blob([s2ab(wbout)], {
      type: "application/octet-stream"
    }), `${filename}.${bookType}`);
  }
function sheet_from_array_of_arrays(data) {
    var ws = {};
    var range = {
      s: {
        c: 10000000,
        r: 10000000
      },
      e: {
        c: 0,
        r: 0
      }
    };
    for (var R = 0; R != data.length; ++R) {
      for (var C = 0; C != data[R].length; ++C) {
        if (range.s.r > R) range.s.r = R;
        if (range.s.c > C) range.s.c = C;
        if (range.e.r < R) range.e.r = R;
        if (range.e.c < C) range.e.c = C;
        var cell = {
          v: data[R][C]
        };
        if (cell.v == null) continue;
        var cell_ref = XLSX.utils.encode_cell({
          c: C,
          r: R
        });
  
        if (typeof cell.v === 'number') cell.t = 'n';
        else if (typeof cell.v === 'boolean') cell.t = 'b';
        else if (cell.v instanceof Date) {
          cell.t = 'n';
          cell.z = XLSX.SSF._table[14];
          cell.v = datenum(cell.v);
        } else cell.t = 's';
  
        ws[cell_ref] = cell;
      }
    }
    if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
    return ws;
  }

这些就是exportExcel.js文件的代码。

(2)使用

<el-button
    class="left"
    v-preventReClick
    size="small"
    type="primary"
    @click="exportData"
>导出</el-button>
exportData() {
      import("@/util/Export2Excel").then((excel) => {
        const multiHeader = [
          [],
        ];
        const tHeader = [];
        const fields = [];
        const values = this.formatJson(fields, table数据);
        const merges = [];
        const setStyleCallBack = (dataInfo) => {
          const borderAll = {
            top: {
              style: "thin",
            },
            bottom: {
              style: "thin",
            },
            left: {
              style: "thin",
            },
            right: {
              style: "thin",
            },
          };
          for (var key in dataInfo) {
            if (key == "!cols" || key == "!merges" || key == "!ref") return;
            dataInfo[key].s = {
              border: borderAll,
              font: {
                name: "宋体",
                sz: 11,
                bold: true,
              },
              alignment: {
                horizontal: "left",
                vertical: "center",
              },
            };
          }
        };
        excel.export_json_to_excel({
          header: tHeader,
          multiHeader,
          data: values,
          merges,
          setStyleCallBack,
          filename: "导出的excel文件名",
        });
      });
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map((v) =>
        filterVal.map((j) => {
          const pathArr = j.split(".");
          let tVal = v;
          pathArr.forEach((key) => {
            tVal = tVal[key];
          });
          return tVal;
        })
      );
    },
 1、 multiHeader:为表头的第一行;
 2、tHeader:为表头的第二行;
 3、fields:为table表格的字段(按照顺序将字段列出来就好啦);
 4、merges:为表格合并设置

比如:

微信图片_20220110145356.png

multiHeader: [
    [
       "序号",
       "预警组织",
        "单位工程",
        "监测项目",
        "监测点编号",
        "批次",
        "初始值",
        "",
        "",
        "上次观测",
        "",
        "",
        "预警结果",
        "累计消除预警次数",
        "消警状态"
    ]
],
tHeader: [
    "",
    "",
    "",
    "",
    "",
    "",
    "初始日期",
    "初始值",
    "校正量",
    "初始日期",
    "初始值",
    "校正量",
    "",
    "",
    ""
],
          

merges的用法:

微信图片_20220110153743.png

merges: [
    "A1:A2",
    "B1:B2",
    "C1:C2",
    "D1:D2",
    "E1:E2",
    "F1:F2",
    "G1:I1",
    "J1:L1",
    "M1:M2",
    "N1:N2",
    "O1:O2",
],

这里注意框起来的部分是多表头,红框设置"G1:I1",篮筐设置"J1:L1",表格上也可以看出从哪个位置开始,到哪个位置结束。

这样多表头导出就可以实现啦!

若有更好的导出方法,欢迎留言推荐!!!