1. 程式人生 > 其它 >vue實現解析表格資料+表格拖拽排序

vue實現解析表格資料+表格拖拽排序

效果圖:
效果演示圖

解析表格

解析表格資料安裝外掛:npm install xlsx --save-dev
安裝完成之後,在頁面進行匯入:import XLSX from 'xlsx'
解析表格用到3個方法

// 點選上傳按鈕,拿到file物件
handleUpload(file) {
    this.readWorkbookFromLocalFile(file, this.outputWorkbook)
    return false;
},
// 通過XLSX.read方法,拿到workbook物件,呼叫回撥函式,解析workbook物件
readWorkbookFromLocalFile (file,
callback) { let reader = new FileReader(); reader.onload = function(e) { let data = e.target.result; let workbook = XLSX.read(data, {type: 'binary'}); if(callback) callback(workbook); }; reader.readAsBinaryString(file); }, // 解析workbook物件,拿到資料,呼叫XLSX.utils.sheet_to_html方法,可以將sheet物件轉換為html字串
outputWorkbook(workbook) { let sheetNames = workbook.SheetNames; // 工作表名稱集合 sheetNames.forEach(name => { let worksheet = workbook.Sheets[name]; // 這裡我們只讀取第一張sheet let html = XLSX.utils.sheet_to_html(worksheet); /** 由於XLSX.utils.sheet_to_html返回的結果是: *<html> <body> <header></header> <table>...</table> </body> </html> *所有需要擷取字串,拿到table標籤即可 */
let sIndex = html.indexOf('<table>') let eIndex = html.indexOf('</table>') this.excelContent = html.slice(sIndex, eIndex + 8) }); },

將擷取完的字串賦值給this.excelContent,可以將表格渲染到頁面上

<div v-html='excelContent' class="table-wrapper" ref="tableWrapper"></div>

表格拖拽

這裡使用HTML5拖拽,主要涉及的知識有:拖拽drag與拖放drop
this.excelContent賦值之後,需要獲取到每一個單元格,為其註冊ondragstart[拖拽開始]ondrag[拖拽中]ondragend[拖拽結束],同時還需要在每一個td標籤增加屬性:draggable="true"

outputWorkbook方法後面新增如下語句:

let tableWrapper = this.$refs.tableWrapper
// 保證頁面上的table渲染完畢
this.$nextTick(() => {
    // 給單元格繫結拖拽事件
    this.tdList = tableWrapper.querySelectorAll('td')
    this.tdList.forEach(item => {
        item.setAttribute('draggable','true');
        this.drag(item)
    })
})

繫結拖拽事件

drag (source) {
   source.ondragstart = this.dragstart
    source.ondrag = this.dragging
    source.ondragend = this.dragend
},

拖拽元素:dragstartdraggingdragend方法具體實現

// 拖拽開始
dragstart (event) {
    event = event || window.event
    const target = event.target
    // 設定樣式
    target.className = 'drop-over-upward'
    // 儲存當前單元格的ID
    event.dataTransfer.setData('id', target.id);
    // 給除當前單元格之外的其它單元格註冊目標拖拽事件
    this.tdList.forEach((item, index) => {
        if (item !== target) {
            item.ondragenter = this.dragenter
            item.ondragover = this.dragover
            item.ondragleave = this.dragleave
            item.ondrop = this.drop
        }
    })
},
// 拖拽中
dragging () {},
// 拖拽結束
dragend (event) {
    event = event || window.event
    const target = event.target
    // 清空樣式
    target.className = ''
    // 清空儲存的資料
    event.dataTransfer.clearData()
    // 給除當前單元格之外的其它單元格移除事件
    this.tdList.forEach((item, index) => {
        if (item !== target) {
            item.ondragenter = null
            item.ondragover = null
            item.ondragleave = null
            item.ondrop = null
        }
    })
},

目標元素:dragenterdragoverdragleavedrop方法具體實現

// 拖拽元素進入目標元素
dragenter (event) {
    event = event || window.event;
    const target = event.target
    target.className = 'drop-over-downward'
},
// 拖拽元素在目標元素中移動
dragover (event) {
    event = event || window.event;
    event.preventDefault()
},
// 拖拽元素離開目標元素
dragleave (event) {
    event = event || window.event;
    const target = event.target
    target.className = ''
},
// 拖拽元素放置在目標元素中
drop (event) {
    event = event || window.event;
    const target = event.target
    target.className = ''
    // 列編號
    let staticArr = ['A', 'B', 'C']
    // td的ID字串'A1'
    let tdIdStr = event.dataTransfer.getData('id').split('-')[1]
    // 將ID通過正則拆分成【‘A’, '1', ''】
    let arr = tdIdStr.split(/(\d+)/)
    // 列字母
    let pre = arr[0]
    // 列Index
    let cIndex = staticArr.findIndex(item => item === pre)
    // 行Index
    let rIndex = parseInt(arr[1]) - 1
    // 通過rIndex、cIndex獲取源ID
    let source = this.$refs.tableWrapper.querySelector('table').querySelectorAll('tr')[rIndex].querySelectorAll('td')[cIndex]
    // 交換內容
    let tempInnerHTML = target.innerHTML
    target.innerHTML = source.innerHTML
    source.innerHTML = tempInnerHTML
}

注意:draggingdragover方法不可以刪除