亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript實(shí)現(xiàn)excel文件導(dǎo)入導(dǎo)出

 更新時(shí)間:2022年06月07日 10:38:47   作者:? 靈扁扁?  ?  
這篇文章主要介紹了JavaScript實(shí)現(xiàn)excel文件導(dǎo)入導(dǎo)出,文件的導(dǎo)入導(dǎo)出是非常常見(jiàn)的需求功能,excel文件的導(dǎo)入導(dǎo)出更為常見(jiàn),實(shí)踐中許多時(shí)候,是調(diào)用接口實(shí)現(xiàn)導(dǎo)入導(dǎo)出的,具體實(shí)現(xiàn)內(nèi)容需要的小伙伴可以參考一下

一、需求場(chǎng)景描述

文件的導(dǎo)入導(dǎo)出是非常常見(jiàn)的需求功能,excel文件的導(dǎo)入導(dǎo)出更為常見(jiàn),實(shí)踐中許多時(shí)候,是調(diào)用接口實(shí)現(xiàn)導(dǎo)入導(dǎo)出的,也就是說(shuō)將文件導(dǎo)入導(dǎo)出的邏輯交給后端去做了。但是,有的時(shí)候確也需要前端自行實(shí)現(xiàn)導(dǎo)入導(dǎo)出,此時(shí)前端實(shí)現(xiàn)導(dǎo)入導(dǎo)出可能是更好的選擇。

1.此時(shí)前端上傳解析excel文件可能更合適

例如,一個(gè)常規(guī)excel文件填寫模板,在用戶的電腦上,用戶上傳完后,還可以在預(yù)覽展示時(shí),在線修改,改完可以下載,也可以將數(shù)據(jù)給到服務(wù)端,但這時(shí),比如這模板數(shù)據(jù)通常不多,比如是一個(gè)團(tuán)隊(duì)成員這樣的數(shù)據(jù),通過(guò)文件流的形式傳給后端,可能不是很理想,倒不如前端解析傳那幾行數(shù)據(jù)就行。

這種場(chǎng)景下,需要前端做到上傳并解析excel文件。

2.此時(shí)前端下載excel文件可能優(yōu)雅一些

支持用戶動(dòng)態(tài)增減篩選數(shù)據(jù)的界面,由于這種頻繁的變更不是實(shí)時(shí)變更到服務(wù)器的,因此服務(wù)器其實(shí)沒(méi)有存有剛剛用戶的增減篩選的操作結(jié)果,此時(shí)由于前端主導(dǎo)下載可能更合適。當(dāng)然,把操作的最終結(jié)果更新到服務(wù)器再告知服務(wù)器提供下載也是可行的。

這種場(chǎng)景下,需要前端做到過(guò)濾解析數(shù)據(jù),然后做excel文件的下載。

實(shí)踐效果圖如下:

二、實(shí)現(xiàn)思路分析

1.導(dǎo)入excel文件實(shí)現(xiàn)思路分析

  • 1.使用html支持上傳標(biāo)簽從本地獲取文件,例如type為file的input,el-upload等。
  • 2.利用FileReader將文件讀取為二進(jìn)制字符串。
  • 3.使用XLSX插件的XLSX.read()方法,將二進(jìn)制字符串轉(zhuǎn)換成excel文件的工作蒲對(duì)象workbook(簡(jiǎn)寫成wb)。
  • 4.通過(guò)XLSX.utils.sheet_to_json()方法,從wb中獲取第一張 Sheets表格數(shù)據(jù)并將其轉(zhuǎn)換為json數(shù)據(jù)。
  • 5.重組json數(shù)據(jù)生成數(shù)組,即是根據(jù)自己的定義的列字段名,重新組成符合自己需求的json數(shù)據(jù)。因?yàn)閺膃xcel中提取的數(shù)據(jù)是沒(méi)有字段名或字段名不符合要求的,

而我們需要渲染在頁(yè)面表格中又確實(shí)需要合適的字段名。

2.導(dǎo)出excel文件實(shí)現(xiàn)思路分析

  • 1.通過(guò)XLSX插件的 XLSX.utils.book_new()方法,創(chuàng)建excel工作蒲對(duì)象wb。
  • 2.按需插入第一行數(shù)據(jù),通過(guò)數(shù)組的unshift()方法。
  • 3.通過(guò)XLSX.utils.json_to_sheet(),創(chuàng)建excel表格對(duì)象ws。
  • 4.通過(guò)json_to_array(key,data),結(jié)合自定義的字段名key,和數(shù)據(jù)記錄data,生成新數(shù)組。
  • 5.通過(guò)auto_width(),對(duì)ws和新生成的數(shù)組,自動(dòng)計(jì)算各列col寬。
  • 6.通過(guò)XLSX.utils.book_append_sheet(),生成實(shí)際excel工作蒲,并使用XLSX.writeFile()生成excel文件。

三、關(guān)鍵代碼

1. exportExcel.js 導(dǎo)出excel文件

/* eslint-disable */
/* 導(dǎo)出excel文件 */

/**
 * 導(dǎo)出excel文件實(shí)現(xiàn)思路分析
 *
 * 1.通過(guò)XLSX插件的 XLSX.utils.book_new()方法,創(chuàng)建excel工作蒲對(duì)象wb。
 * 2.按需插入第一行數(shù)據(jù),通過(guò)數(shù)組的unshift()方法。
 * 3.通過(guò)XLSX.utils.json_to_sheet(),創(chuàng)建excel表格對(duì)象ws。
 * 4.通過(guò)json_to_array(key,data),結(jié)合自定義的字段名key,和數(shù)據(jù)記錄data,生成新數(shù)組。
 * 5.通過(guò)auto_width(),對(duì)ws和新生成的數(shù)組,自動(dòng)計(jì)算各列col寬。
 * 6.通過(guò)XLSX.utils.book_append_sheet(),生成實(shí)際excel工作蒲,并使用XLSX.writeFile()生成excel文件。
 */

import XLSX from 'xlsx'

// 自動(dòng)計(jì)算col列寬
function auto_width (ws, data) {
  /*set worksheet max width per col*/
  const colWidth = data.map(row => row.map(val => {
    /*if null/undefined*/
    if (val == null) {
      return { 'wch': 10 }
    }
    /*if chinese*/
    else if (val.toString().charCodeAt(0) > 255) {
      return { 'wch': val.toString().length * 2 }
    } else {
      return { 'wch': val.toString().length }
    }
  }))
  /*start in the first row*/
  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
}

// 將json數(shù)據(jù)轉(zhuǎn)換成數(shù)組
function json_to_array (key, jsonData) {
  return jsonData.map(v => key.map(j => {
    return v[j]
  }))
}

/**
 * @param header Object,表頭
 * @param data Array,表體數(shù)據(jù)
 * @param key Array,字段名
 * @param title String,標(biāo)題(會(huì)居中顯示),即excel表格第一行
 * @param filename String,文件名
 * @param autoWidth Boolean,是否自動(dòng)根據(jù)key自定義列寬度
 */
export const exportJsonToExcel = ({
  header,
  data,
  key,
  title,
  filename,
  autoWidth
}) => {
  const wb = XLSX.utils.book_new()
  if (header) {
    data.unshift(header)
  }
  if (title) {
    data.unshift(title)
  }
  const ws = XLSX.utils.json_to_sheet(data, {
    header: key,
    skipHeader: true
  })
  if (autoWidth) {
    const arr = json_to_array(key, data)
    auto_width(ws, arr)
  }
  XLSX.utils.book_append_sheet(wb, ws, filename)
  XLSX.writeFile(wb, filename + '.xlsx')
}
export default {
  exportJsonToExcel
}

2. importExcel.js 導(dǎo)入excel文件

/* eslint-disable */
/* 導(dǎo)入excel文件 */

/**
 * 導(dǎo)入excel文件實(shí)現(xiàn)思路分析
 *
 * 1.使用html支持上傳標(biāo)簽從本地獲取文件,例如type為file的input,el-upload等。
 * 2.利用FileReader將文件讀取為二進(jìn)制字符串。
 * 3.使用XLSX插件的XLSX.read()方法,將二進(jìn)制字符串轉(zhuǎn)換成excel文件的工作蒲對(duì)象workbook(簡(jiǎn)寫成wb)。
 * 4.通過(guò)XLSX.utils.sheet_to_json()方法,從wb中獲取第一張 Sheets表格數(shù)據(jù)并將其轉(zhuǎn)換為json數(shù)據(jù)。
 * 5.重組json數(shù)據(jù)生成數(shù)組,即是根據(jù)自己的定義的列字段名,重新組成符合自己需求的json數(shù)據(jù)。因?yàn)閺膃xcel中提取的數(shù)據(jù)是沒(méi)有字段名或字段名不符合要求的,
 * 而我們需要渲染在頁(yè)面表格中又確實(shí)需要合適的字段名。
 */


/**
 * @param file 文件流
 * @param tableTemplate 要導(dǎo)入的表格模板,一個(gè)數(shù)組,如:
 * tableTemplate: ['userCode', 'userName', 'department', 'major', 'position'],其中的值
 * 為表格的字段名,注意字段的順序應(yīng)與實(shí)際的導(dǎo)入excel一致。
 */
export default function importExcel (file, tableTemplate) {
  return new Promise((resolve, reject) => {
    let f = file.raw // 獲取文件內(nèi)容
    // 通過(guò)DOM取文件數(shù)據(jù)
    let rABS = false // 是否將文件讀取為二進(jìn)制字符串
    let reader = new FileReader()
    FileReader.prototype.readAsBinaryString = function (f) {
      let binary = ''
      let rABS = false // 是否將文件讀取為二進(jìn)制字符串
      let wb // 讀取完成的數(shù)據(jù)
      let outdata
      let reader = new FileReader()
      reader.onload = function (e) {
        let bytes = new Uint8Array(reader.result)
        let length = bytes.byteLength
        for (let i = 0; i < length; i++) {
          binary += String.fromCharCode(bytes[i])
        }
        let XLSX = require('xlsx')
        if (rABS) {
          wb = XLSX.read(btoa(binary), { // 手動(dòng)轉(zhuǎn)化
            type: 'base64'
          })
        } else {
          wb = XLSX.read(binary, {
            type: 'binary'
          })
        }
        outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]) // outdata就是表格中的值

        let arr = []
        // 下面是數(shù)據(jù)解析提取邏輯
        if (tableTemplate.length > 0) {
          let tempArr = Object.keys(outdata[0])
          let tempArrNew = []
          for (let i in tempArr) {
            for (let k in tableTemplate) {
              if (i === k) {
                tempArrNew.push({fieldE: tableTemplate[k], fieldC: tempArr[i]})
              }
            }
          }

          tempArr = tempArrNew
          outdata.map(item => {
            let obj = {}
            tempArr.map(temp2 => {
              obj[temp2.fieldE] = item[temp2.fieldC]
            })
            arr.push(obj)
          })
        }

        resolve(arr)
      }
      reader.readAsArrayBuffer(f)
    }

    if (rABS) {
      reader.readAsArrayBuffer(f)
    } else {
      reader.readAsBinaryString(f)
    }
  })
}

四、使用示例

1.使用示例一:上傳解析excel

關(guān)鍵 html 代碼部分

<el-upload
        action=""
        id="upload-excel"
        :on-change="handleChange"
        :show-file-list="false"
        accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
        :auto-upload="false">
</el-upload>

<el-table
        class="cn-table-th-bg"
        size="small"
        :data="tableData"
        border
        style="width: 100%">
    <el-table-column type="index" label="序號(hào)" width="50" align="center"></el-table-column>
    <el-table-column prop="userSource" label="來(lái)源" align="center"></el-table-column>
    <el-table-column prop="userCode" label="工號(hào)" align="center"></el-table-column>
    <el-table-column prop="userName" label="姓名" align="center"></el-table-column>
    <el-table-column prop="department" label="部門" align="center"></el-table-column>
    <el-table-column prop="major" label="專業(yè)" align="center"></el-table-column>
    <el-table-column prop="position" label="職務(wù)/職稱" align="center"></el-table-column>
    <el-table-column label="操作" align="center" width="250">
        <template slot-scope="scope">
            <el-button @click="clickDelete(scope.row)" size="mini">刪除</el-button>
            <el-button @click="moveUp(tableData,scope.$index)" size="mini" class="up-button">上移</el-button>
            <el-button @click="moveDown(tableData,scope.$index)" size="mini" class="down-button">下移</el-button>
        </template>
    </el-table-column>
</el-table>

// 關(guān)鍵 js 代碼部分

import importExcel from '@/utils/excel/importExcel'

handleChange (file, fileList) {
    tableField: ['userCode', 'userName', 'department', 'major', 'position'],
    importExcel(file, tableField).then(res => {
       this.tableData = res
   })
}

2.使用示例二:下載excel文件

關(guān)鍵 js 代碼

import { exportJsonToExcel } from '@/utils/excel/exportExcel'

clickDownload () {
        const tableField = ['userCode', 'userName', 'department', 'major', 'position'],
            tableHeader = {userCode: '工號(hào)', userName: '姓名', department: '部門', major: '專業(yè)', position: '職位/職稱'},
            tableTitle = '導(dǎo)出表格',
            templateData = [
              {'userCode': 'N1001', 'userName': '張三', 'department': '綜合管理部', 'major': '計(jì)算機(jī)科學(xué)與技術(shù)', 'position': '項(xiàng)目經(jīng)理'}
            ],
            obj = {
              header: tableHeader,
              data: templateData,
              key: tableField,
              title: '',
              filename: '團(tuán)隊(duì)成員導(dǎo)入模板',
              autoWidth: true
           }
        exportJsonToExcel(obj)
},

到此這篇關(guān)于JavaScript實(shí)現(xiàn)excel文件導(dǎo)入導(dǎo)出的文章就介紹到這了,更多相關(guān)JS文件導(dǎo)入導(dǎo)出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論