vue实现解析表格数据+表格拖拽排序

2 篇文章 0 订阅
1 篇文章 0 订阅

效果图:
效果演示图

解析表格

解析表格数据安装插件: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方法不可以删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值