從0-1超詳細教你實現前端讀取excel表格並渲染到界面


@

  • 本文旨在解決無需調用后端接口,實現前端讀取表格文件,獲取文件內容,渲染到界面的需求
  • 我的其他文章可以解決擴展需求:
  • 讀取解析表格后執行自動單元格合並
  • 讀取解析表格后根據數據對比分析自動設置單元格顏色
  • 讀取解析表格后執行數據分析(透析)生成可滿足用戶自定義需求的echarts關系圖
  • 下載界面表格功能

說明

公司平時做后台管理系統比較多,類似需求更是十分常見,我也寫過類似帖子,但是都是只放代碼從來不寫注釋和步驟,嘿嘿,話不多說,此文章為完整的記錄:

前提

平時我經常使用的是:
Ant Design + Angular
Element UI + Vue
Ant Design + Vue
方便起見,今天我們使用Element UI + Vue
基於vue-element-admin直接開始

代碼倉庫

1.碼雲地址
2.github地址

步驟一:准備工作

  1. 點擊進入vue-element-admin下載
    在這里插入圖片描述
  2. 下載解壓在這里插入圖片描述
  3. 安裝依賴、運行在這里插入圖片描述
    在這里插入圖片描述在這里插入圖片描述
  4. 運行成功在這里插入圖片描述
    在這里插入圖片描述

步驟二:實現導入表格解析

  1. 進入以下路徑;

src\views\dashboard\index.vue

  1. 刪除無用代碼,准備開始;
<template>
 <div class="dashboard-container">
   
 </div>
</template>

<script>
export default {
 name: 'Dashboard'
}
</script>

<style lang="scss" scoped>

</style>

在這里插入圖片描述

  1. 增加 導入 按鈕,保存刷新;
<template>
  <div class="dashboard-container">
    <!-- 導入按鈕 -->
    <div class="button_group">
      <a
        href="javascript:;"
        class="button_s my_file el-button button_s el-button--primary el-button--small"
      >
        <input type="file" class="my_input" @change="importExcel" id="upload" />導入
      </a>
    </div>
    <!-- 導入按鈕 -->
  </div>
</template>

<script>
export default {
  name: 'Dashboard',
  methods: {
    /**
     * 導入表格
     */
     importExcel(e) {
      
    }
  }
}
</script>

<style lang="scss" scoped>
// 按鈕樣式
.button_group {
  .button_s {
    width: 78px;
    margin: 5px 10px 5px 5px;
  }
  .button_m {
    width: 100px;
    margin: 5px 10px 5px 5px;
  }
  .my_file {
    position: relative;
    .my_input {
      position: absolute;
      opacity: 0;
      width: 78px;
      height: 30px;
      top: 0;
      left: 0;
    }
  }
}
// 按鈕樣式
</style>

在這里插入圖片描述

  1. 下載xlsx 、引入;在這里插入圖片描述
    在這里插入圖片描述

  2. 編寫導入表格 功能、保存刷新;

<script>
import xlsx from "xlsx";
export default {
  name: 'Dashboard',
  methods: {
    /**
     * 導入表格
     */
     importExcel(e) {
      const files = e.target.files;
      console.log(files);
      if (!files.length) {
        return ;
      } else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
        return alert("上傳格式不正確,請上傳xls或者xlsx格式");
      }
      const fileReader = new FileReader();
      fileReader.onload = ev => {
        try {
          const data = ev.target.result;
          const XLSX = xlsx;
          const workbook = XLSX.read(data, {
            type: "binary"
          });
          const wsname = workbook.SheetNames[0]; //取第一張表,wb.SheetNames[0]是獲取Sheets中第一個Sheet的名字
          const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格內容,wb.Sheets[Sheet名]獲取第一個Sheet的數據
          const excellist = []; //清空接收數據
          //編輯數據
          for (var i = 0; i < ws.length; i++) {
            excellist.push(ws[i]);
          }
          console.log("讀取結果", excellist); // 此時得到的是一個內容是對象的數組需要處理
        } catch (e) {
          return alert("讀取失敗!");;
        }
      };
      fileReader.readAsBinaryString(files[0]);
      var input = document.getElementById("upload");
      input.value = "";
    }
  }
}
</script>
  1. 編寫如下表格,用來測試功能在這里插入圖片描述
    在這里插入圖片描述
    在這里插入圖片描述

  2. 有時候,表格題目是中文,讀取后我們想要得到英文屬性名,那么 增加如下代碼 、再次測試;

<script>
import xlsx from "xlsx";
export default {
  name: 'Dashboard',
  methods: {
    getHeader(sheet) {
      const XLSX = xlsx;
      const headers = [];
      const range = XLSX.utils.decode_range(sheet["!ref"]); // worksheet['!ref'] 是工作表的有效范圍
      let C;
      /* 獲取單元格值 start in the first row */
      const R = range.s.r; // 行 // C 列
      let i = 0;
      for (C = range.s.c; C <= range.e.c; ++C) {
        var cell =
          sheet[
            XLSX.utils.encode_cell({ c: C, r: R })
          ]; /* 根據地址得到單元格的值find the cell in the first row */
        var hdr = "UNKNOWN" + C; // 如果有空表頭,會替換為您想要的默認值replace with your desired default
        // XLSX.utils.format_cell 生成單元格文本值
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell);
        if(hdr.indexOf('UNKNOWN') > -1){
          if(!i) {
            hdr = '__EMPTY';
          }else {
            hdr = '__EMPTY_' + i;
          }
          i++;
        }
        headers.push(hdr);
      }
      return headers;
    },
    /**
     * 導入表格
     */
     importExcel(e) {
      const files = e.target.files;
      console.log(files);
      if (!files.length) {
        return ;
      } else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
        return alert("上傳格式不正確,請上傳xls或者xlsx格式");
      }
      const fileReader = new FileReader();
      fileReader.onload = ev => {
        try {
          const data = ev.target.result;
          const XLSX = xlsx;
          const workbook = XLSX.read(data, {
            type: "binary"
          });
          const wsname = workbook.SheetNames[0]; //取第一張表,wb.SheetNames[0]是獲取Sheets中第一個Sheet的名字
          const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格內容,wb.Sheets[Sheet名]獲取第一個Sheet的數據
          const excellist = []; //清空接收數據
          //編輯數據
          for (var i = 0; i < ws.length; i++) {
            excellist.push(ws[i]);
          }
          console.log("讀取結果", excellist); // 此時得到的是一個內容是對象的數組需要處理
          // 獲取表頭2-1
          const a = workbook.Sheets[workbook.SheetNames[0]];
          const headers = this.getHeader(a);
          console.log('headers', headers);
          // 獲取表頭2-2
        } catch (e) {
          return alert("讀取失敗!");;
        }
      };
      fileReader.readAsBinaryString(files[0]);
      var input = document.getElementById("upload");
      input.value = "";
    }
  }
}
</script>

我們把表格改成不規則狀態、保存、打開界面測試
在這里插入圖片描述
在這里插入圖片描述

步驟三:實現表格渲染

  1. 界面增加 表格組件
<!-- 表格組件 -->
    <div class="myTable">
      <el-table
        max-height="600"
        :data="dataArr"
        v-loading="tableLoading"
        :span-method="objectSpanMethod"
        border
        style="width: 100%"
      >
        <el-table-column
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          v-for="(item, i) in tableColumn"
          :key="i"
        ></el-table-column>
      </el-table>
    </div>
    <!-- 表格組件 -->
data() {
    return {
      dataArr: [], // 表格內容數據數組
      // countArr: {}, // 分析表格數據以及表頭,得到一個對照數組,用來進行自定義合並,本文暫時只寫基礎,不介紹自動合並單元格了喲~~我的其他文章有寫自定義合並實現方法~
      tableColumn: [], // 表格表頭配置數組
      tableLoading: false // 表格是否loading
    };
  },

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
2. 增加 表格渲染方法

備注:表格渲染方法中有一部分代碼是用來映射中英文屬性名的,這個是我增加的一個功能,有時候也不不需要使用,可以按自己需求來修改代碼;

setTable(headers, excellist) {
      const tableTitleData = []; // 存儲表格表頭數據
      const tableMapTitle = {}; // 設置表格內容中英文對照用
      headers.forEach((_, i) => {
        tableMapTitle[_] = "prop" + i;
        tableTitleData.push({
          prop: "prop" + i,
          label: _,
          width: 100
        });
      });
      console.log("tableTitleData", tableTitleData);
      // 映射表格內容屬性名為英文
      const newTableData = [];
      excellist.forEach(_ => {
        const newObj = {};
        Object.keys(_).forEach(key => {
          newObj[tableMapTitle[key]] = _[key];
        });
        newTableData.push(newObj);
      });
      console.log('newTableData',newTableData);
      this.tableColumn = tableTitleData;
      this.dataArr = newTableData;
    },

在這里插入圖片描述

  1. 調用 表格渲染方法
		// 在importExcel(e)方法中添加下面代碼
          // 渲染表格1-1
          this.setTable(headers, excellist);
          // 渲染表格1-2

在這里插入圖片描述

  1. 功能測試在這里插入圖片描述
    在這里插入圖片描述

結語

本代碼支持不規則數據,沒有表頭的也可以渲染到界面哦~~
歡迎大家指出我代碼的錯誤~
如果有更好的寫法,歡迎大家提出來,共同進步喲~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM