【JS】类Excel选中的JS实现

1️⃣ Eg

在这里插入图片描述

2️⃣ About

1. 监听鼠标的 按下 & 移动 & 抬起
  • onmousedown
  • onmousemove
  • onmouseup
document.onmousedown = (e) => {
    document.onmousemove = (e2) => {
        selectHandle(e.pageX, e.pageY, e2.pageX, e2.pageY)
    }
    document.onmouseup = (e3) => {
        cleanSelect()
        document.onmousemove = null
    }
}

按下 (onmousedown) 时拿到开始坐标并记录,移动 (onmousemove) 后的结果坐标为结束坐标,在两坐标 x轴 & y轴 相交范围内的 Dom 即为需要添加选中的
在这里插入图片描述
鼠标抬起 (onmouseup) 时清空鼠标移动监听

2. 选中状态的添加

document.elementFromPoint(x, y)
用到了根据坐标获取 Dom元素,同时也是实现的关键

(这个函数印象中我几乎没有实际使用过 🤔

/**
* 选中处理
* @param beginX
* @param beginY
* @param endX
* @param endY
*/
const selectHandle = (beginX, beginY, endX, endY) => {
    cleanSelect()
    /**
    * x - 记录当前列的坐标 x,在一列处理完后根据 dom元素 的(宽度 + x坐标)进行累加
    * y - 记录当前行的坐标 y,在一行处理完后根据 dom元素 的(高度 + y坐标)进行累加
    * isReverseY - Y轴移动方向,向上移动为 true,向下为 false
    * isReverseX - X轴移动方向,向左移动为 true,向右为 false
    * range - 允许的选中偏差
    */
    let x = beginX, y = beginY, isReverseY = beginY > endY, isReverseX = beginX > endX, range = 10
    const xHandle = () => {
        const yHandle = () => {
            let e = document.elementFromPoint(x, y)
            if (e) {
                addDomToArr(e)
                y = isReverseY ? e.offsetTop - range : e.clientHeight + e.offsetTop + range
                if (isReverseY ? y >= endY : y <= endY) xHandle()
            }
        }
        let e = document.elementFromPoint(x, y)
        if (e) {
            yHandle()
            y = beginY
            x = isReverseX ? e.offsetLeft - range : e.clientWidth + e.offsetLeft + range
            if (isReverseX ? x >= endX : x <= endX) xHandle()
        }
    }
    xHandle()
    
    // 改变选中元素的边框颜色
    arr.forEach(v => {
        v.style.border = '2px solid #F8CBA6'
    })
}
/**
* 将dom元素添加至 `arr(已选中)`
* @param dom
*/
const addDomToArr = (dom) => {
    if (dom.parentNode.getAttribute('class') != 'container') return
    let has = false
    arr.forEach(v => {
        // 判断是否已存在
        if (v.offsetLeft == dom.offsetLeft && v.offsetTop == dom.offsetTop) {
            has = true
            return
        }
    })
    if (!has) arr.push(dom)
}
Source Code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>9</div>
    <div>10</div>
    <div>11</div>
    <div>12</div>
    <div>13</div>
    <div>14</div>
    <div>15</div>
    <div>16</div>
    <div>17</div>
    <div>18</div>
    <div>19</div>
    <div>20</div>
</div>
</body>
 
<script>
    let items, arr = []
    window.onload = () => {
        items = document.querySelector('.container').children
        document.onmousedown = (e) => {
            document.onmousemove = (e2) => {
                selectHandle(e.pageX, e.pageY, e2.pageX, e2.pageY)
            }
            document.onmouseup = (e3) => {
                cleanSelect()
                document.onmousemove = null
            }
        }
    }
 
    /**
     * 选中处理
     * @param beginX
     * @param beginY
     * @param endX
     * @param endY
     */
    const selectHandle = (beginX, beginY, endX, endY) => {
        cleanSelect()
        /**
         * 采用按列添加选中的方式
         * eg: 从 1,1 移动至 3,3
         *      * -> ** -> ***
         *      * -> ** -> ***
         *      * -> ** -> ***
         *
         * x - 记录当前列的坐标 x,在一列处理完后根据 dom元素 的(宽度 + x坐标)进行累加
         * y - 记录当前行的坐标 y,在一行处理完后根据 dom元素 的(高度 + y坐标)进行累加
         * isReverseY - Y轴移动方向,向上移动为 true,向下为 false
         * isReverseX - X轴移动方向,向左移动为 true,向右为 false
         * range - 允许的选中偏差
         */
        let x = beginX, y = beginY, isReverseY = beginY > endY, isReverseX = beginX > endX, range = 10
        const xHandle = () => {
            const yHandle = () => {
                let e = document.elementFromPoint(x, y)
                if (e) {
                    addDomToArr(e)
                    y = isReverseY ? e.offsetTop - range : e.clientHeight + e.offsetTop + range
                    if (isReverseY ? y >= endY : y <= endY) xHandle()
                }
            }
            let e = document.elementFromPoint(x, y)
            if (e) {
                yHandle()
                y = beginY
                x = isReverseX ? e.offsetLeft - range : e.clientWidth + e.offsetLeft + range
                if (isReverseX ? x >= endX : x <= endX) xHandle()
            }
        }
        xHandle()
 
        // 改变选中元素的边框颜色
        arr.forEach(v => {
            v.style.border = '2px solid #F8CBA6'
        })
    }
 
    /**
     * 将dom元素添加至 `arr(已选中)`
     * @param dom
     */
    const addDomToArr = (dom) => {
        if (dom.parentNode.getAttribute('class') != 'container') return
        let has = false
        arr.forEach(v => {
            // 判断是否已存在
            if (v.offsetLeft == dom.offsetLeft && v.offsetTop == dom.offsetTop) {
                has = true
                return
            }
        })
        if (!has) arr.push(dom)
    }
 
    /**
     * 清空已选中
     */
    const cleanSelect = () => {
        arr = []
        for (let i = 0; i < items.length; i++) {
            items[i].style.border = '2px solid #FFFBEB00'
        }
    }
 
</script>
 
 
 
<style>
    body {
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: #ECF9FF;
        min-width: 100vw;
        min-height: 100vh;
        margin: unset;
    }
 
    .container {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr 1fr;
        gap: 1px;
        background-color: #FFE7CC;
    }
 
    .container div {
        padding: 20px 50px;
        background-color: white;
        user-select: none;
        border: 2px solid #FFFBEB00;
        color: #F99417;
    }
</style>
</html>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
通过Java和JavaScript可以实现Excel的导入和导出,具体实现方式如下: 1. Excel导出 Java代码: ``` public void exportExcel(HttpServletResponse response, List<MyData> dataList) throws IOException { // 创建工作簿对象 Workbook workbook = new HSSFWorkbook(); // 创建工作表对象 Sheet sheet = workbook.createSheet("Sheet1"); // 创建表头行对象 Row headerRow = sheet.createRow(0); // 设置表头单元格样式 CellStyle headerCellStyle = workbook.createCellStyle(); headerCellStyle.setAlignment(HorizontalAlignment.CENTER); // 创建表头单元格对象 Cell headerCell1 = headerRow.createCell(0); headerCell1.setCellValue("名称"); headerCell1.setCellStyle(headerCellStyle); Cell headerCell2 = headerRow.createCell(1); headerCell2.setCellValue("年龄"); headerCell2.setCellStyle(headerCellStyle); Cell headerCell3 = headerRow.createCell(2); headerCell3.setCellValue("性别"); headerCell3.setCellStyle(headerCellStyle); Cell headerCell4 = headerRow.createCell(3); headerCell4.setCellValue("地址"); headerCell4.setCellStyle(headerCellStyle); // 遍历数据列表,创建数据行对象 int rowIndex = 1; for (MyData data : dataList) { Row dataRow = sheet.createRow(rowIndex++); dataRow.createCell(0).setCellValue(data.getName()); dataRow.createCell(1).setCellValue(data.getAge()); dataRow.createCell(2).setCellValue(data.getGender()); dataRow.createCell(3).setCellValue(data.getAddress()); } // 设置响应头 response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=data.xls"); // 输出Excel文件 workbook.write(response.getOutputStream()); workbook.close(); } ``` JavaScript代码: ``` function exportExcel() { // 发送GET请求获取数据 axios.get('/data') .then(response => { // 创建Blob对象 const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' }); // 创建URL const url = URL.createObjectURL(blob); // 创建a标签并设置下载属性 const link = document.createElement('a'); link.href = url; link.download = 'data.xls'; // 模拟点击a标签进行下载 link.click(); // 释放URL对象 URL.revokeObjectURL(url); }) .catch(error => { console.error(error); }); } ``` 上面的代码中,我们首先创建了一个Java方法来导出Excel文件,并通过JavaScript发送GET请求将数据获取到客户端。然后,我们将数据转换为Blob对象,并创建URL,再创建a标签并设置下载属性,最后模拟点击a标签进行下载。 2. Excel导入 Java代码: ``` public List<MyData> importExcel(MultipartFile file) throws IOException { List<MyData> dataList = new ArrayList<>(); // 创建工作簿对象 Workbook workbook = WorkbookFactory.create(file.getInputStream()); // 获取工作表对象 Sheet sheet = workbook.getSheetAt(0); // 遍历数据行,将数据添加到列表中 for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) { Row row = sheet.getRow(rowIndex); if (row != null) { MyData data = new MyData(); data.setName(row.getCell(0).getStringCellValue()); data.setAge((int) row.getCell(1).getNumericCellValue()); data.setGender(row.getCell(2).getStringCellValue()); data.setAddress(row.getCell(3).getStringCellValue()); dataList.add(data); } } workbook.close(); return dataList; } ``` JavaScript代码: ``` function importExcel() { const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.accept = '.xls,.xlsx'; fileInput.addEventListener('change', () => { // 获取文件对象 const file = fileInput.files[0]; // 创建FormData对象 const formData = new FormData(); formData.append('file', file); // 发送POST请求上传文件 axios.post('/data', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) .then(response => { // 处理响应数据 console.log(response.data); }) .catch(error => { console.error(error); }); }); fileInput.click(); } ``` 上面的代码中,我们首先创建了一个Java方法来导入Excel文件,并通过JavaScript创建了一个文件选择框,并监听文件选择事件,将选中的文件上传到服务器。然后,服务器将文件解析为数据列表并返回给客户端,我们在响应处理中进行数据处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值