IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 【vue + Excel表格导入与导出】导入Excel并展示在el-table表格中,表格导出为Excel文件 -> 正文阅读

[JavaScript知识库]【vue + Excel表格导入与导出】导入Excel并展示在el-table表格中,表格导出为Excel文件

注:末尾有完整代码

效果图

在这里插入图片描述

Excel

在这里插入图片描述

1、下载依赖

xlsx是导入所需依赖
file-saver是导出所需依赖

npm install xlsx --save
npm install file-saver --save

2、组件中导入

import * as XLSX from "xlsx/xlsx.mjs";
import FileSaver from "file-saver";

3、html部分

el-upload内部分属性:

action:必填字段,这里没有填服务器地址。
:auto-upload=“false”:将文件进行截取,避免上传,配合action属性使用
:on-change=“handle”: 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用

el-table:el-table-column序号显示可根据需求删除

<template>
  <div id="Excel">
    <!-- 上传 -->
    <el-upload
      action
      accept=".xlsx, .xls"
      :auto-upload="false"
      :show-file-list="false"
      :on-change="handle"
    >
      <el-button type="primary" class="imExcelBtn"
        >导入Excel</el-button>
    </el-upload>

    <!-- 表格名称及导出和关闭预览的按钮 -->
    <div class="excelName" v-if="tableKey">
      <div class="left"></div>
      <div class="center">{{ excelName }}</div>
      <div class="right">
        <el-button type="success" @click="exportExcel">导出为Excel</el-button>
        <el-button type="danger" @click="closeExcel">关闭预览</el-button>
      </div>
    </div>
    <!-- 表格 -->
    <el-table
      :data="tableData"
      style="width: 100%"
      max-height="500"
      :key="tableKey"
      :header-cell-style="{
        background: '#d2d28e',
        color: '#000000',
      }"
      v-if="tableKey"
      id="excelTable"
      border
      stripe
    >
    <!-- 第一个el-table-column 可根据需求删除-->
      <el-table-column
        header-align="center"
        align="center"
        type="index"
        label="序号"
        width="50"
      ></el-table-column>
      <el-table-column
        v-for="(item, index) in tableColumn"
        :key="index"
        :prop="item.prop"
        :label="item.label"
        width="width"
      >
      </el-table-column>
    </el-table>
  </div>
</template>

4、data部分

data() {
    return {
      tableKey: false, //表格的key及显示与隐藏
      excelName: "", //excel表格名称
      excelHeader: [], //excel的表头
      tableData: [], //表格数据
      tableColumn: [], //表格的表头
    };
  },

5、methods内函数

// 上传文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
    async handle(ev) {
      //改变表格key值
      this.tableKey = true;
      let file = ev.raw;
      this.excelName = file.name;
      //截取表格文件名
      this.excelName = this.excelName.substring(0, this.excelName.lastIndexOf("."));
      console.log("上传的未解析源文件", file);
      if (!file) {
        console.log("文件打开失败");
        return;
      } else {
        let data = await this.readFile(file);
        let workbook = XLSX.read(data, { type: "binary" }); //解析二进制格式数据
        console.log("二进制数据的解析:", workbook);
        let worksheet = workbook.Sheets[workbook.SheetNames[0]]; //获取第一个Sheet
        // 调用解析表头方法
        this.getHeader(worksheet);
        let result = XLSX.utils.sheet_to_json(worksheet); //转换为json数据格式
        console.log("最终解析的 json 格式数据:", result);
        this.tableData = result;
        // 调用处理表头函数
        this.setTable();
      }
    },
//文件读取
readFile(file) {
      return new Promise((resolve) => {
        let reader = new FileReader();
        reader.readAsBinaryString(file); //以二进制的方式读取
        reader.onload = (ev) => {
          resolve(ev.target.result);
        };
      });
    },
// 解析出表格表头
    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);
      }
      // 保存至data中
      this.excelHeader = headers;
      return headers;
    },
// 设置表格中英文映射
    setTable() {
      const headers = this.excelHeader;
      const excellist = this.tableData;
      const tableTitleData = []; // 存储表格表头数据
      const tableMapTitle = {}; // 设置表格内容中英文对照用
      headers.forEach((_, i) => {
        tableMapTitle[_] = "prop" + i;
        tableTitleData.push({
          prop: "prop" + i,
          label: _,
          width: 100,
        });
      });
      console.log("表格头标题:", tableTitleData);
      // 映射表格内容属性名为英文
      const newTableData = [];
      excellist.forEach((_) => {
        const newObj = {};
        Object.keys(_).forEach((key) => {
          newObj[tableMapTitle[key]] = _[key];
        });
        newTableData.push(newObj);
      });
      console.log("表格数据:", newTableData);
      this.tableColumn = tableTitleData;
      this.tableData = newTableData;
    },
将表格导出为Excel的函数

== ‘fileName.xlsx’:==导出的文件名称,可自行设置

//导出表格为Excel
    exportExcel() {
      /* generate workbook object from table */
      let xlsxParam = { raw: true } // 导出的内容只做解析,不进行格式转换
      let table = document.querySelector('#excelTable').cloneNode(true)
      //这里是双下划线
      // table.removeChild(table.querySelector('.el-table__fixed')) 
      let wb = XLSX.utils.table_to_book(table, xlsxParam)

      /* get binary string as output */
      let wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
      try {
        FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), 'fileName.xlsx')
      } catch (e) {
        if (typeof console !== 'undefined') {
          console.log(e, wbout)
        }
      }
      return wbout
    },

6、样式部分

<style lang='less' scoped>
.excelName {
  display: flex;
  justify-content: space-between;
  font-size: 30px;
  margin-bottom: 20px;
}
.imExcelBtn {
  margin: 10px 0;
}
</style>

完整代码

<template>
  <div id="Excel">
    <!-- 上传 -->
    <el-upload
      action
      accept=".xlsx, .xls"
      :auto-upload="false"
      :show-file-list="false"
      :on-change="handle"
    >
      <el-button type="primary" class="imExcelBtn"
        >导入Excel</el-button
      >
    </el-upload>

    <!-- 表格名称及导出和关闭预览的按钮 -->
    <div class="excelName" v-if="tableKey">
      <div class="left"></div>
      <div class="center">{{ excelName }}</div>
      <div class="right">
        <el-button type="success" @click="exportExcel">导出为Excel</el-button>
        <el-button type="danger" @click="closeExcel">关闭预览</el-button>
      </div>
    </div>
    <!-- 表格 -->
    <el-table
      :data="tableData"
      style="width: 100%"
      max-height="500"
      :key="tableKey"
      :header-cell-style="{
        background: '#d2d28e',
        color: '#000000',
      }"
      v-if="tableKey"
      id="excelTable"
      border
      stripe
    >
    <!-- 第一个el-table-column 可根据需求删除-->
      <el-table-column
        header-align="center"
        align="center"
        type="index"
        label="序号"
        width="50"
      ></el-table-column>
      <el-table-column
        v-for="(item, index) in tableColumn"
        :key="index"
        :prop="item.prop"
        :label="item.label"
        width="width"
      >
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
import * as XLSX from "xlsx/xlsx.mjs";
import FileSaver from "file-saver";
export default {
  name: "Excel",
  data() {
    return {
      tableKey: false, //表格的key及显示与隐藏
      excelName: "", //excel表格名称
      excelHeader: [], //excel的表头
      tableData: [], //表格数据
      tableColumn: [], //表格的表头
    };
  },
  methods: {
    readFile(file) {
      //文件读取
      return new Promise((resolve) => {
        let reader = new FileReader();
        reader.readAsBinaryString(file); //以二进制的方式读取
        reader.onload = (ev) => {
          resolve(ev.target.result);
        };
      });
    },
    // 上传文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
    async handle(ev) {
      //改变表格key值
      this.tableKey = true;
      let file = ev.raw;
      this.excelName = file.name;
      //截取表格文件名
      this.excelName = this.excelName.substring(
        0,
        this.excelName.lastIndexOf(".")
      );
      console.log("上传的未解析源文件", file);
      if (!file) {
        console.log("文件打开失败");
        return;
      } else {
        let data = await this.readFile(file);
        let workbook = XLSX.read(data, { type: "binary" }); //解析二进制格式数据
        console.log("二进制数据的解析:", workbook);
        let worksheet = workbook.Sheets[workbook.SheetNames[0]]; //获取第一个Sheet
        // 调用解析表头方法
        this.getHeader(worksheet);
        let result = XLSX.utils.sheet_to_json(worksheet); //转换为json数据格式
        console.log("最终解析的 json 格式数据:", result);
        this.tableData = result;
        // 调用处理表头函数
        this.setTable();
      }
    },
    // 解析出表格表头
    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);
      }
      // 保存至data中
      this.excelHeader = headers;
      return headers;
    },
    // 设置表格中英文映射
    setTable() {
      const headers = this.excelHeader;
      const excellist = this.tableData;
      const tableTitleData = []; // 存储表格表头数据
      const tableMapTitle = {}; // 设置表格内容中英文对照用
      headers.forEach((_, i) => {
        tableMapTitle[_] = "prop" + i;
        tableTitleData.push({
          prop: "prop" + i,
          label: _,
          width: 100,
        });
      });
      console.log("表格头标题:", tableTitleData);
      // 映射表格内容属性名为英文
      const newTableData = [];
      excellist.forEach((_) => {
        const newObj = {};
        Object.keys(_).forEach((key) => {
          newObj[tableMapTitle[key]] = _[key];
        });
        newTableData.push(newObj);
      });
      console.log("表格数据:", newTableData);
      this.tableColumn = tableTitleData;
      this.tableData = newTableData;
    },
    // 关闭表格预览
    closeExcel() {
      this.tableKey = false;
      //表格数据置空
      this.tableData = [];
      this.tableColumn = [];
    },
    //导出表格为Excel
    exportExcel() {
      /* generate workbook object from table */
      let xlsxParam = { raw: true } // 导出的内容只做解析,不进行格式转换
      let table = document.querySelector('#excelTable').cloneNode(true)
      //这里是双下划线
      // table.removeChild(table.querySelector('.el-table__fixed')) 
      let wb = XLSX.utils.table_to_book(table, xlsxParam)

      /* get binary string as output */
      let wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
      try {
        FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), 'fileName.xlsx')
      } catch (e) {
        if (typeof console !== 'undefined') {
          console.log(e, wbout)
        }
      }
      return wbout
    },
  },
};
</script>

<style lang='less' scoped>
.excelName {
  display: flex;
  justify-content: space-between;
  font-size: 30px;
  margin-bottom: 20px;
}
.imExcelBtn {
  margin: 10px 0;
}
</style>

导入部分参考文章:

Vue 前端解析 Excel 数据
从0-1超详细教你实现前端读取excel表格并渲染到界面

导出部分参考文章:

vue导出Excel——elementUI表格导出功能

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章           查看所有文章
加:2022-10-17 12:24:08  更:2022-10-17 12:28:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/11 17:04:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码