因为我的项目中有需要要展现excel(内容只有一些简略的地址/地区等信息,没有简单的款式,只是蕴含了一些合并的表格),所以利用XLSX的读写性能,对读取后的数据进行二次解决并展现。

成果截图在最下边

先上代码(间接从我的项目中摘抄出一部分,并附上了正文):

//过后我的项目用的是vue,为了省事只将有用的局部筛选了进去<template>  <div class="about">    <button @click="createBook">生成excel</button>    <br>    <input type="file" id="inputFile" @change="fileChange">    <table id="tableView" style="min-width: 100%; border-collapse:collapse; border: 1px solid;">      <tr v-for="(item, index) in dataSource" :key="index" style="height: 28px;">        <template v-for="(sub, subIndex) in item" :key="subIndex">          <td v-if="sub.rowspan !== 0 && sub.colspan !== 0"              :rowspan="sub.rowspan || 1" :colspan="sub.colspan || 1"              style="width: auto; min-width: 120px; padding: 3px 5px; border: 1px solid;">            {{sub.name}}          </td>        </template>      </tr>    </table>  </div></template><script>  import {axios} from '@/utils/request'  const XLSX = require('@/utils/xlsx.full.min')  export default {    data() {      return {        dataSource: [],      }    },    methods: {      //获取本地文件      fileChange() {        let files = document.getElementById('inputFile').files        this.fileReader(files[0])      },      // //获取网络文件      // getNetworkFile(url) {      //   axios({      //     url,   //文件地址      //     method: 'get',      //     responseType: 'blob'      //   }).then(blobData => {      //     console.log(blobData)      //     //将blob转为file类型      //     let file = new File([blobData], '样例', {type: blobData.type})      //     this.fileReader(file)      //   })      // },      fileReader(file) {        let reader = new FileReader()        //读入file        reader.readAsBinaryString(file)        reader.onload = e => {          let data = e.target.result          //读取file, 提取数据          let workbook = XLSX.read(data, {type: 'binary', cellStyles: true})          console.log(workbook)          // workbook.SheetNames 是工作表名称的有序列表          // workbook.Sheets 是一个对象,其键是工作表名称,其值是工作表对象          this.sheetNames = workbook.SheetNames          this.sheets = workbook.Sheets          //默认显示第一个sheet          this.parsingTable(this.sheets[this.sheetNames[0]])        }      },      //对数据进行解决,实现表格合并展现的性能      parsingTable(table) {        let header = []  //表格列        let keys = Object.keys(table)        let maxRowIndex = 0  //最大行数        //!ref工作表范畴        if (table['!ref'] && table['!ref'].includes(':')) {          let refs = table['!ref'].split(':')          maxRowIndex = refs[1].replace(/[A-Z]/g, '')        }        for (let [i, h] of keys.entries()) {          //提取key中的英文字母          let col = h.replace(/[^A-Z]/g, '')          //单元格是以A-1的模式展现的,所以排除蕴含!的key          h.indexOf('!') === -1 && header.indexOf(col) === -1 && header.push(col)          //如果!ref不存在时,  设置某一列最初一个单元格的索引为最大行数          if ((!table['!ref'] || !table['!ref'].includes(':')) && header.some(c => table[`${c}${i}`])) {            maxRowIndex = i > maxRowIndex ? i : maxRowIndex          }        }        header = header.sort((a, b) => a.localeCompare(b))  //按字母程序排序 [A, B, ..., E, F]        // console.log(header)        // console.log(maxRowIndex)        let dataSource = []   //表格数据        //excel的行示意为 1, 2, 3, ......, 所以index起始为1        for (let index = 1; index <= maxRowIndex; index++) {          let row = []  //行          //每行的单元格汇合, 例: [A1, ..., F1]          row = header.map(item => {            let key = `${item}${index}`            let cell = table[key]            return {              key,              name: cell ? cell.v : '',              // style: cell ? cell.s : '',   //单元格的款式/主题, 有些不实用            }          })          dataSource.push(row)        }        //合并单元格        if (table['!merges']) {          for (let item of table['!merges']) {            //s开始  e完结  c列  r行  (行、列的索引都是从0开始的)            for (let r = item.s.r; r <= item.e.r; r++) {              for (let c = item.s.c; c <= item.e.c; c++) {                // console.log('=======', r, c)                //查找单元格时须要r+1                //例:单元格A1的地位是{c: 0, r:0}                let rowIndex = r + 1                if (!dataSource[r]) {                  dataSource.splice(r, 0, header.map(col => ({key: `${col}${rowIndex}`})))                }                let cell = dataSource[r].find(a => a.key === `${header[c]}${rowIndex}`)                cell.rowspan = 0                cell.colspan = 0              }            }            //合并时保留范畴内左上角的单元格            let start = `${header[item.s.c]}${item.s.r + 1}`            // let end = `${header[item.e.c]}${item.e.r + 1}`            // console.log(start)            let cell = dataSource[item.s.r].find(a => a.key === start)            cell.rowspan = item.s.r !== item.e.r ? item.e.r - item.s.r + 1 : 1   //纵向合并            cell.colspan = item.s.c !== item.e.c ? item.e.c - item.s.c + 1 : 1   //横向合并          }        }        console.log(dataSource)        this.dataSource = dataSource      },      createBook() {        //应用table_to_sheet或table_to_book其中一种办法        //table_to_sheet的用法        let worksheet = XLSX.utils.table_to_sheet(document.getElementById('tableView'))        let workbook = {          SheetNames: [],          Sheets: {}        }        workbook.SheetNames.push('sheet1')        worksheet['!cols'] = [{wch: 20}] //设置第一列的列宽        workbook.Sheets['sheet1'] = worksheet        //table_to_book的用法        // let workbook = XLSX.utils.table_to_book(document.getElementById('tableView'));        let data = XLSX.write(workbook, {          bookType: 'xlsx', // 要生成的文件类型          type: 'array'        })        let blobData = new Blob([data], {type: 'application/octet-stream'})        this.downFile(blobData)      },      downFile(blobData) {        if (typeof window.navigator.msSaveBlob !== 'undefined') {          window.navigator.msSaveBlob(new Blob([blobData]), new Date().getTime() + '.xlsx')        } else {          let url = window.URL.createObjectURL(new Blob([blobData]))          let link = document.createElement('a')          link.style.display = 'none'          link.href = url          link.setAttribute('download', new Date().getTime() + '.xlsx')          document.body.appendChild(link)          link.click()          document.body.removeChild(link)          window.URL.revokeObjectURL(url)        }      }    },  }</script>

本地文件(款式是我本人加的,读取或写入款式须要将cellStyles设置为true):

页面渲染的table(只实现了表格合并,没有对其余款式进行解决):

导出后的文件: