spreadjs实现类似于企业微信的协同提示

news2024/11/5 15:53:58

核心代码

import * as GC from "@grapecity-software/spread-sheets";

function HighlightLayout(name:string){
    this.name = name;
    this._eventNs = ".HighlightLayout" + name || "";
    this._sheetRangesInfo = {}
}
HighlightLayout.prototype.bind = function(spread:GC.Spread.Sheets.Workbook){
    if(spread){
        this._content = spread;
        this._container = this._createLayoutContainer(spread.getHost())
        this._bindEvents(spread);
    }
}
HighlightLayout.prototype._createLayoutContainer = function(host:HTMLElement){
    host.style.position = "relative";
    var container = document.createElement('div');
    container.style.cssText = "position: absolute;height: 100%;width: 100%;top: 0px;left: 0px;pointer-events: none";
    host.appendChild(container)
    return container;
}
HighlightLayout.prototype._bindEvents = function(context:GC.Spread.Sheets.Workbook){
    var self = this;
    context.bind(GC.Spread.Sheets.Events.TopRowChanged + self._eventNs, function (e, data) {
        setTimeout(function(){
            self._resetLayout();
        },0);
    });
    context.bind(GC.Spread.Sheets.Events.LeftColumnChanged + self._eventNs, function (e, data) {
        setTimeout(function(){
            self._resetLayout();
        },0);
    });
    context.bind(GC.Spread.Sheets.Events.ColumnWidthChanged + self._eventNs, function (e, data) {
        setTimeout(function(){
            self._resetLayout();
        },0);
    });
    context.bind(GC.Spread.Sheets.Events.RowHeightChanged + self._eventNs, function (e, data) {
        setTimeout(function(){
            self._resetLayout();
        },0);
    });
    context.bind(GC.Spread.Sheets.Events.FormulatextboxActiveSheetChanged + self._eventNs, function (e, data) {
        setTimeout(function(){
            self._resetLayout();
        },0);
    });
}

HighlightLayout.prototype._resetLayout = function(id){
    var content = this._content,
        container = this._container,
        sheet = content.getActiveSheet();

    //clear Layout
    container.innerHTML = "";

    var rangesInfo = this._sheetRangesInfo[sheet.name()];
    if(!rangesInfo){
        return;
    }
    for(var id in rangesInfo){
        var info = rangesInfo[id];
        if(!info.ranges){
            continue;
        }
        for(var i = 0; i < info.ranges.length; i++){
            this._paintRange(container, id + "_" + i,sheet, info.ranges[i], info.option,id)
        }
    }
}
HighlightLayout.prototype._paintRange = function(container:any, id:any, sheet:any, hightlightRange:any, option:any,name:string){
    const noneBorderStyle = "none",
        highlightBorderStyle = "3px solid " + (option && option.borderColor) || "lightseagreen";
    var tlRect = {},rbRect = {};
    var actualArea = {};
    for(var i = hightlightRange.row; i < hightlightRange.row + hightlightRange.rowCount; i++){
        var breakFlag = false;
        for(var j = hightlightRange.col; j < hightlightRange.col + hightlightRange.colCount; j++){
            var rect = sheet.getCellRect(i, j);
            if(rect.x != null){
                tlRect = rect;
                actualArea.rowStart = i;
                actualArea.colStart = j;
                breakFlag = true;
                break;
            }
        }
        if(breakFlag){
            break
        }
    }
    for(var i = hightlightRange.row + hightlightRange.rowCount - 1; i >= hightlightRange.row; i--){
        var breakFlag = false;
        for(var j = hightlightRange.col + hightlightRange.colCount - 1; j >= hightlightRange.col; j--){
            var rect = sheet.getCellRect(i, j);
            if(rect.x != null){
                rbRect = rect;
                actualArea.rowEnd = i;
                actualArea.colEnd = j;
                breakFlag = true;
                break;
            }
        }
        if(breakFlag){
            break
        }
    }
    var trRect = sheet.getCellRect(actualArea.rowStart, actualArea.colEnd),
        lbRect = sheet.getCellRect(actualArea.rowEnd, actualArea.colStart),
        cornerRect = sheet.getCellRect(0, 0, -1, -1);
    var viewportWidth = cornerRect.width + sheet.getViewportWidth(0) + sheet.getViewportWidth(1),
        viewportHeight = cornerRect.height + sheet.getViewportHeight(0) + sheet.getViewportHeight(1);

    var x = tlRect.x || lbRect.x,
        y = tlRect.y || trRect.y,
        endX = trRect.x != undefined && (trRect.x + trRect.width) || rbRect.x != undefined && (rbRect.x + rbRect.width),
        endY = rbRect.y != undefined && (rbRect.y + rbRect.height) || lbRect.y != undefined && (lbRect.y + lbRect.height);

    var left = x && x - cornerRect.width >= 0,
        top = y && y - cornerRect.height >= 0,
        right = endX && endX <= viewportWidth,
        bottom = endY && endY <= viewportHeight;

    if(!(left || top || right || bottom)){
        return;
    }
    x = left ? x : cornerRect.width;
    y = top ? y : cornerRect.height;
    endX = right ? endX : viewportWidth;
    endY = bottom ? endY : viewportHeight;
    var rectWidth= endX - x,
        rectHeight = endY - y;

    var highLightRect = document.createElement('div');
    highLightRect.id = id;
    highLightRect.style.position = "absolute";
    highLightRect.style.pointerEvents = "none";

    highLightRect.style.left = x - 2 + "px";
    highLightRect.style.top = y - 2 + "px";
    highLightRect.style.height = rectHeight - 2 + "px";
    highLightRect.style.width = rectWidth - 2 + "px";

    highLightRect.style.borderLeft = left ? highlightBorderStyle : noneBorderStyle;
    highLightRect.style.borderTop = top ? highlightBorderStyle : noneBorderStyle;
    highLightRect.style.borderRight = right ? highlightBorderStyle : noneBorderStyle;
    highLightRect.style.borderBottom = bottom ? highlightBorderStyle : noneBorderStyle;
    //改变位置的代码在这
    highLightRect.innerHTML = '<div style="position:absolute;right:0px;top:0px;transform:translateY(-100%);width: 80px;height: 20px;text-align:center;background-color:#1B9AF7;font-size: 12px;">' + name + '</div>'
    container.appendChild(highLightRect);
}

HighlightLayout.prototype.addRanges = function(sheetName, id, ranges, option){
    if(sheetName && id && ranges && ranges.length){
        var rangesInfo = this._sheetRangesInfo[sheetName];
        if(!rangesInfo){
            this._sheetRangesInfo[sheetName] = rangesInfo = {};
        }
        rangesInfo[id] = {ranges, option}
        this._resetLayout(id);
    }
}

export default HighlightLayout

调用

<template>
  <div ref="ssDesigner" style="width:100%;height:98vh;border:1px solid darkgray"></div>
</template>

<script setup lang="ts">
import "@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2016colorful.css";
import "@grapecity-software/spread-sheets-designer/styles/gc.spread.sheets.designer.min.css"
import "@grapecity-software/spread-sheets-designer-resources-cn"
import * as GC from "@grapecity-software/spread-sheets";
import * as GC2 from "@grapecity-software/spread-sheets-designer"
import "@grapecity-software/spread-sheets-vue";
import HighlightLayout from "./components/HeightLightLayout.ts"

import {onMounted,ref} from "vue";

const ssDesigner = ref(null);

onMounted(() => {
  if(ssDesigner.value){
    const divElement = ssDesigner.value as HTMLDivElement;
    if(divElement)
    {
      var designer = new GC2.Spread.Sheets.Designer.Designer(divElement);
      if(designer){
        const spread = designer.getWorkbook() as GC.Spread.Sheets.Workbook;
        //const sheet = spread?.getActiveSheet();
        let highlightLayout = new HighlightLayout();
        highlightLayout.bind(spread)
        highlightLayout.addRanges("Sheet1", "wjl等",
            [new GC.Spread.Sheets.Range(1, 1, 1, 1), new GC.Spread.Sheets.Range(1, 1, 1, 1)], { borderColor: "lightGreen" })
      }
    }else{
      console.log('divElement不存在')
    }
  }
})
</script>

<style scoped>

</style>

在这里插入图片描述
如果想多个就Add多个就行

highlightLayout.addRanges("Sheet1", "wjl等",
    [new GC.Spread.Sheets.Range(1, 1, 1, 1), new GC.Spread.Sheets.Range(1, 1, 1, 1)], { borderColor: "lightGreen" })
highlightLayout.addRanges("Sheet1", "cs等",
    [new GC.Spread.Sheets.Range(2, 2, 1, 1), new GC.Spread.Sheets.Range(2, 2, 1, 1)], { borderColor: "lightGreen" })

在这里插入图片描述

参考

https://demo.grapecity.com.cn/spreadjs/practice/cell/highlight-area-and-add-tag
https://jscodemine.grapecity.com/share/mpNp1KNJm0qbm0HYvAE1fA/
https://gcdn.grapecity.com.cn/showtopic-199661-1-152.html
https://gcdn.grapecity.com.cn/showtopic-148906-1-1.html
https://gcdn.grapecity.com.cn/showtopic-148123-1-332.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2230846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux云计算 |【第五阶段】PROJECT3-DAY1

主要内容&#xff1a; 跳板机&#xff08;堡垒机&#xff09;的概念、部署JumpeServer 一、跳板机&#xff08;堡垒机&#xff09;的概念 跳板机&#xff08;Jump Server 或 Bastion Host&#xff09;是一种网络安全设备或服务器&#xff0c;也称堡垒机&#xff0c;是一类可作…

PAT甲级-1133 Splitting A Linked List

题目 题目大意 给定一个链表的首节点地址和节点个数&#xff0c;以及一个数k。要求重新排列该链表&#xff0c;使其按<0 &#xff0c;> 0 && < k&#xff0c;>k 的顺序排序。但是不改变原有顺序&#xff0c;比如-4 -> -6 -> -2&#xff0c;不需要再…

重新回顾反向传播与梯度下降:训练神经网络的基石

有关反向传播与梯度下降&#xff1a;流程与公式推导 背景前向传播反向传播 背景 反向传播则是一种训练神经网络的算法&#xff0c;目前我们使用的深度学习模型大都是通过这种方法训练的。它的核心思想是通过计算损失函数相对于每个参数的导数&#xff0c;来更新神经网络中的权重…

Java | Leetcode Java题解之第524题通过删除字母匹配到字典里最长单词

题目&#xff1a; 题解&#xff1a; class Solution {public String findLongestWord(String s, List<String> dictionary) {int m s.length();int[][] f new int[m 1][26];Arrays.fill(f[m], m);for (int i m - 1; i > 0; --i) {for (int j 0; j < 26; j) {…

PHP合成图片,生成海报图,poster-editor使用说明

之前写过一篇使用Grafika插件生成海报图的文章&#xff0c;但是当我再次使用时&#xff0c;却发生了错误&#xff0c;回看Grafika文档&#xff0c;发现很久没更新了&#xff0c;不兼容新版的GD&#xff0c;所以改用了intervention/image插件来生成海报图。 但是后来需要对海报…

机器人领域中的scaling law:通过复现斯坦福机器人UMI——探讨数据规模化定律(含UMI的复现关键)

前言 在24年10.26/10.27两天&#xff0c;我司七月在线举办的七月大模型机器人线下营时&#xff0c;我们带着大家一步步复现UMI「关于什么是UMI&#xff0c;详见此文&#xff1a;UMI——斯坦福刷盘机器人&#xff1a;从手持夹持器到动作预测Diffusion Policy(含代码解读)」&…

丝杆支撑座的更换与细节注意事项

丝杆支撑座是支撑连接丝杆和电机的轴承支撑座&#xff0c;分固定侧和支撑侧&#xff0c;它们都有用预压调整的JIS5级的交界处球轴承。在自动化设备中是常用的传动装置&#xff0c;作为核心部件&#xff0c;对设备精度、稳定性和生产效率产生直接影响。在长时间运行中&#xff0…

行业深耕+全球拓展双轮驱动,用友U9 cloud加速中国制造全球布局

竞争加剧、供应链动荡、出海挑战……在日益激烈的市场竞争和新的全球化格局中&#xff0c;中国制造业的数智化转型已经步入深水区。 作为面向中型和中大型制造业的云ERP&#xff0c;用友U9 cloud一直是中国制造业转型升级的参与者和见证者。自2021年发布以来&#xff0c;用友U…

C#实现word和pdf格式互转

1、word转pdf 使用nuget&#xff1a; Microsoft.Office.Interop.Word winform页面&#xff1a; 后端代码&#xff1a; //using Spire.Doc; //using Spire.Pdf; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using Sy…

Spring MVC 完整生命周期和异常处理流程图

先要明白 // 1. 用户发来请求: localhost:8080/user/1// 2. 处理器映射器(HandlerMapping)的工作 // 它会找到对应的Controller和方法 GetMapping("/user/{id}") public User getUser(PathVariable Long id) {return userService.getById(id); }// 3. 处理器适配…

wps宏代码学习

推荐学习视频&#xff1a;https://space.bilibili.com/363834767/channel/collectiondetail?sid1139008&spm_id_from333.788.0.0 打开宏编辑器和JS代码调试 工具-》开发工具-》WPS宏编辑器 左边是工程区&#xff0c;当打开多个excel时会有多个&#xff0c;要注意不要把…

vscode | 开发神器vscode快捷键删除和恢复

目录 快捷键不好使了删除快捷键恢复删除的快捷键 在vscode使用的过程中&#xff0c;随着我们自身需求的不断变化&#xff0c;安装的插件将会持续增长&#xff0c;那么随之而来的就会带来一个问题&#xff1a;插件的快捷键重复。快捷键重复导致的问题就是快捷键不好使了&#xf…

Java-02

笔试算法&#xff1a; 41. 回文串 我们称一个字符串为回文串&#xff0c;当且仅当这个串从左往右和从右往左读是一样的。例如&#xff0c;aabbaa、a、abcba 是回文串&#xff0c;而 ab、ba、abc 不是回文串。注意单个字符也算是回文串。 现在&#xff0c;给你一个长度为n的…

《数字图像处理基础》学习05-数字图像的灰度直方图

目录 一&#xff0c;数字图像的数值描述 &#xff11;&#xff0c;二值图像 &#xff12;&#xff0c;灰度图像 3&#xff0c;彩色图像 二&#xff0c;数字图像的灰度直方图 一&#xff0c;数字图像的数值描述 在之前的学习中&#xff0c;我知道了图像都是二维信息&…

6.1、实验一:静态路由

源文件获取&#xff1a;6.1_实验一&#xff1a;静态路由.pkt: https://url02.ctfile.com/f/61945102-1420248902-c5a99e?p2707 (访问密码: 2707) 一、目的 理解路由表的概念 会使用基础命令 根据需求正确配置静态路由 二、准备实验 1.实验要求 让PC0、PC1、PC2三台电脑…

集成ruoyi-it管理系统,遇到代码Bug

前言&#xff1a;这次ruoyi框架开发it管理系统&#xff0c;出现很多问题&#xff0c;也有学到很多东西&#xff0c;出现几个问题&#xff0c;希望下次项目不会出现或者少出现问题&#xff1b;其中还是有很多基础知识有些忘记&#xff0c;得多多复习 1&#xff1a;当写的代码没…

解决Redis缓存穿透(缓存空对象、布隆过滤器)

文章目录 背景代码实现前置实体类常量类工具类结果返回类控制层 缓存空对象布隆过滤器结合两种方法 背景 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会打到数据库 常见的解决方案有两种&#xff0c;分别…

基于微信小程序的校园失物招领系统的研究与实现(V4.0)

博主介绍&#xff1a;✌stormjun、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

vscode 创建 vue 项目时,配置文件为什么收缩到一起展示了?

一、前言 今天用 vue 官方脚手架创建工程&#xff0c;然后通过 vscode 打开项目发现&#xff0c;配置文件都被收缩在一起了。就像下面这样 这有点反直觉&#xff0c;他们应该是在同一层级下的&#xff0c;怎么会这样&#xff0c;有点好奇&#xff0c;但是打开资源管理查看&…

LInux系统编程(二)操作系统和进程

目录 一、前言&#xff1a;冯诺依曼体系结构 1、图中各个单元的介绍 2、值得注意的几点 二、操作系统 1、操作系统分层图 2、小总结 三、 进程&#xff08;重点&#xff09; 1、进程的基本概念 2、存放进程信息的数据结构——PCB&#xff08;Linux 下称作 task_struct…