JS的EXCEL库之xlsx.js

2,740 阅读3分钟

作为前端开发,很多时候不得不需要导入excel表格并解析展示到页面上,或者前端要进行简单的表格数据校验;这种时候我们就可以使用xlsx这个js库了;该库处理excel异常强大!!!

一、Vue中如何导入并读取Excel数据

一、导入并读取Excel功能从整体上来说两种方式,一是前端解析文件后将数据返回给后端,另一种是前端直接将Excel文档返回后台,由后台进行处理。使用哪种方法需要根据具体业务需求,下面简单介绍第一种方法:由前端解析数据
1、引入依赖

npm install -S file-saver xlsx

npm install -D script-loader

npm install xlsx
2、在main.js中引入XLSX

import XLSX from ‘xlsx’
Vue.use(XLSX)
3、前面环境和依赖完成之后,我们开始创建Import.vue页面,放一个button上传按钮。

各参数说明可参考官方文档:www.jianshu.com/p/84b727a4b…

<el-upload
    class="upload-demo"
    action=""
    :on-change="handleChange"
    :on-remove="handleRemove"
    :on-exceed="handleExceed"
    :limit="limitUpload"
    accept="application/vnd.openxmlformats-    
    officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
    :auto-upload="false">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>

123456789101112

4、定义所需要的方法,代码如下(为了美观,加入了一些提示语和提示框)

    //上传文件时处理方法  
    handleChange(file, fileList){
        this.fileTemp = file.raw;
        if(this.fileTemp){
            if((this.fileTemp.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') 
                || (this.fileTemp.type == 'application/vnd.ms-excel')){
                this.importfxx(this.fileTemp);
            } else {
                this.$message({
                    type:'warning',
                    message:'附件格式错误,请删除后重新上传!'
                })
            }
        } else {
            this.$message({
                type:'warning',
                message:'请上传附件!'
            })
        }
    },
    //超出最大上传文件数量时的处理方法
    handleExceed(){
        this.$message({
            type:'warning',
            message:'超出最大上传文件数量的限制!'
        })
        return;
    },
    //移除文件的操作方法
    handleRemove(file,fileList){
        this.fileTemp = null
    },

1234567891011121314151617181920212223242526272829303132

最重要的读取excel文件的方法:

     importfxx(obj) {
        let _this = this;
        let inputDOM = this.$refs.inputer;
        // 通过DOM取文件数据

        this.file = event.currentTarget.files[0];

        var rABS = false; //是否将文件读取为二进制字符串
        var f = this.file;

        var reader = new FileReader();
        //if (!FileReader.prototype.readAsBinaryString) {
        FileReader.prototype.readAsBinaryString = function(f) {
            var binary = "";
            var rABS = false; //是否将文件读取为二进制字符串
            var pt = this;
            var wb; //读取完成的数据
            var outdata;
            var reader = new FileReader();
            reader.onload = function(e) {
                var bytes = new Uint8Array(reader.result);
                var length = bytes.byteLength;
                for (var i = 0; i < length; i++) {
                    binary += String.fromCharCode(bytes[i]);
                }
                //如果没有在main.js中引入,则此处需要引入,用于解析excel
                // var XLSX = require("xlsx");
                if (rABS) {
                    wb = XLSX.read(btoa(fixdata(binary)), {
                    //手动转化
                    type: "base64"
                    });
                } else {
                    wb = XLSX.read(binary, {
                    type: "binary"
                    });
                }
                outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); 
                //outdata就是读取的数据(不包含标题行即表头,表头会作为对象的下标)
                //此处可对数据进行处理
                // let arr = [];
                // outdata.map(v => {
                //     let obj = {}
                //     obj.code = v['Code']
                //     obj.name = v['Name']
                //     obj.pro = v['province']
                //     obj.cit = v['city']
                //     obj.dis = v['district']
                //     arr.push(obj)
                // });
                // _this.da=arr;
                // _this.dalen=arr.length;
                return arr;
            };
            reader.readAsArrayBuffer(f);
        };
        if (rABS) {
            reader.readAsArrayBuffer(f);
        } else {
            reader.readAsBinaryString(f);
        }
    }

二、Vue中如何导出Excel数据

//html
<el-table  id="integration-table" >
    <el-table-column prop="c9331" label="id"></el-table-column>
    <el-table-column prop="c5605" label="姓名"></el-table-column>
    <el-table-column prop="c9351" label="年龄"></el-table-column>
</el-table>
 
 
//js
import FileSaver from 'file-saver'
import XLSX from 'xlsx'
    // 定义导出Excel表格事件
    exportExcel () {
      /* 从表生成工作簿对象 */
      var wb = XLSX.utils.table_to_book(document.querySelector(' #integration-table'))
      /* 获取二进制字符串作为输出 */
      var wbout = XLSX.write(wb, {
        bookType: 'xlsx',
        bookSST: true,
        type: 'array'
      })
      try {
        // Blob 对象表示一个不可变、原始数据的类文件对象。
        // Blob 表示的不一定是JavaScript原生格式的数据。
        // File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
        // 返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。
        FileSaver.saveAs(
          new Blob([wbout], { type: 'application/octet-stream' }),
          // 设置导出文件名称
          '用户表.xlsx')
      } catch (e) {
        if (typeof console !== 'undefined') console.log(e, wbout)
      } return wbout
    },

通过数据插入导出(json转excel格式导出)

封装工具类

import fs from 'file-saver'
import * as XLSX from 'xlsx'
 
 
export function xlsx(json, fields, filename = '.xlsx') {//导出xlsx
  json.forEach(item => {
    for (let i in item) {
      if (fields.hasOwnProperty(i)) {
        item[fields[i]] = item[i];
      }
      delete item[i]; //删除原先的对象属性
    }
  })
  let sheetName = filename //excel的文件名称
  let wb = XLSX.utils.book_new()  //工作簿对象包含一SheetNames数组,以及一个表对象映射表名称到表对象。XLSX.utils.book_new实用函数创建一个新的工作簿对象。
  let ws = XLSX.utils.json_to_sheet(json, { header: Object.values(fields) }) //将JS对象数组转换为工作表。
  wb.SheetNames.push(sheetName)
  wb.Sheets[sheetName] = ws
  const defaultCellStyle = { font: { name: "Verdana", sz: 13, color: "FF00FF88" }, fill: { fgColor: { rgb: "FFFFAA00" } } };//设置表格的样式
  let wopts = { bookType: 'xlsx', bookSST: false, type: 'binary', cellStyles: true, defaultCellStyle: defaultCellStyle, showGridLines: false }  //写入的样式
  let wbout = XLSX.write(wb, wopts)
  let blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' })
  fs.saveAs(blob, filename + '.xlsx')
}
 
const s2ab = s => {
  var buf;
  if (typeof ArrayBuffer !== 'undefined') {
    buf = new ArrayBuffer(s.length)
    var view = new Uint8Array(buf)
    for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
    return buf
  } else {
    buf = new Array(s.length);
    for (let i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
    return buf;
  }
}
 

页面中使用

<template>
  <div id="app">
    <div><el-button type="success" @click="outExcel">导出excel</el-button></div>
    <el-table
    :data="jsonData"
    stripe
    style="width: 100%">
    <el-table-column
      prop="id"
      label="学号"
      width="180">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      width="180">
    </el-table-column>
    <el-table-column
      prop="age"
      label="年龄">
    </el-table-column>
      <el-table-column
      prop="classes"
      label="学院">
    </el-table-column>
  </el-table>
  </div>
</template>
 
<script>
import {xlsx} from './utils/xlsx'
 
export default {
  data() {
    return {
      jsonData:[{
        id:'1',
        name:'小智',
        age:18,
        classes:'商学院'
        
      },
      {
        id:'2',
        name:'小白',
        age:19,
        classes:'商学院'
        
      },
      {
        id:'3',
        name:'小蓝',
        age:12,
        classes:'商学院'
        
      },
      {
        id:'4',
        name:'小花',
        age:14,
        classes:'商学院'
        
      },
      {
        id:'5',
        name:'小粉',
        age:15,
        classes:'商学院'
        
      },
      {
        id:'6',
        name:'小黄',
        age:16,
        classes:'商学院'
        
      },
      {
        id:'7',
        name:'小红',
        age:17,
        classes:'商学院'
        
      },
      {
        id:'8',
        name:'小黑',
        age:19,
        classes:'商学院'
        
      },
      ],
      listHander:{
        id:'学号',
        name:'姓名',
        age:'年龄',
        classes:'学院'
      }
    }
  },
  methods: {
    outExcel(){
        // this.jsonData是要导出的数据内容(表格里的内容),
        // this.listHander对应要导出内容的表头
        // 学生:指向的是excel文件名
      xlsx(this.jsonData,this.listHander,'学生')
    }
  },
}
</script>
 
<style>
 
</style>