SpreadJS 集成使用案例

news2025/1/17 0:48:50

SpreadJS 集成案例

介绍:

SpreadJS 基于 HTML5 标准,支持跨平台开发和集成,支持所有主流浏览器,无需预装任何插件或第三方组件,以原生的方式嵌入各类应用,可以与各类后端技术框架相结合。SpreadJS 以 纯前端、跨平台的能力,让应用系统轻松获得与原生
Excel 一致的交互体验。 前端集成:

实现效果:

在这里插入图片描述

代码实现:

1) : 创建项目

Cmd 依次执行命令:

C:\Users\zhaoQiang\Desktop>vue create spreadjs

C:\Users\zhaoQiang\Desktop>cd spreadjs

安装插件:

npm install 以下插件: 或根据使用需求安装所需要的插件:

在这里插入图片描述

Main.js引用:

在这里插入图片描述

App.vue编写界面:

在这里插入图片描述

2) Ribbon工具栏添加测试菜单和事件

在这里插入图片描述

3) 监听Excel单元格变化:

// SpreadJs 初始化完毕事件中获取WorkBook对象。
this.designer = value;
this.spread = this.designer.getWorkbook();

监听单元格选中事件和单元格编辑结束事件:

在这里插入图片描述

4) JSON数据转换:

本地JSON数据转换为界面上表格:

在这里插入图片描述

表格界面获取JSON数据:

在这里插入图片描述

代码地址

https://gitee.com/zhaoqhero/spreadjs.

官方文档

官网地址:https://www.grapecity.com.cn/developer/spreadjs

API文档:https://demo.grapecity.com.cn/spreadjs/help/api/modules/GC.Data

官方案例:https://demo.grapecity.com.cn/spreadjs/SpreadJSTutorial/quickstart/quickstart-vue

附图

在这里插入图片描述

主要代码

Package.json

{
  "name": "spreadjs",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@grapecity/spread-excelio": "^17.0.0",
    "@grapecity/spread-sheets": "^17.0.0",
    "@grapecity/spread-sheets-barcode": "^17.0.0",
    "@grapecity/spread-sheets-charts": "^17.0.0",
    "@grapecity/spread-sheets-designer": "^17.0.0",
    "@grapecity/spread-sheets-designer-resources-cn": "^17.0.0",
    "@grapecity/spread-sheets-designer-resources-en": "^17.0.0",
    "@grapecity/spread-sheets-designer-vue": "^17.0.0",
    "@grapecity/spread-sheets-io": "^17.0.0",
    "@grapecity/spread-sheets-languagepackages": "^17.0.0",
    "@grapecity/spread-sheets-pdf": "^17.0.0",
    "@grapecity/spread-sheets-pivot-addon": "^17.0.0",
    "@grapecity/spread-sheets-print": "^17.0.0",
    "@grapecity/spread-sheets-shapes": "^17.0.0",
    "@grapecity/spread-sheets-tablesheet": "^17.0.0",
    "@grapecity/spread-sheets-vue": "^17.0.0",
    "core-js": "^3.8.3",
    "vue": "^3.2.13"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead",
    "not ie 11"
  ]
}

Main.js

import {createApp} from 'vue'
import App from './App.vue'
import Designer from "@grapecity/spread-sheets-designer-vue"

let app = createApp(App);
app.component("gc-spread-sheets-designer", Designer);
app.mount('#app');

App.vue


<template>
  <div id="gc-designer-container" style="display: flex;flex-direction: row">
    <div>
      <gc-spread-sheets-designer
          id="designer"
          :styleInfo="styleInfo"
          :config="config"
          :spreadOptions="spreadOptions"
          @designerInitialized="designerInitialized">
      </gc-spread-sheets-designer>
    </div>
    <div>
      <div class="textarea-container">{{ changingText }}</div>
      <div class="textarea-container">{{ currentTxt }}</div>
      <button style="height: 40px;margin-left:20px;width: 100px" @click="fromJson">json数据添加</button>
      <button style="height: 40px;margin-left:20px;width: 100px" @click="toJson">json数据获取</button>

      <div class="textarea-container" style="height: 400px">{{ sheetJsonStr }}</div>
    </div>
  </div>
</template>

<script>

import '@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css';
import "@grapecity/spread-sheets-designer/styles/gc.spread.sheets.designer.min.css";
import * as GC from "@grapecity/spread-sheets";
import "@grapecity/spread-sheets-print";
import "@grapecity/spread-sheets-shapes";
import "@grapecity/spread-sheets-pivot-addon";
import "@grapecity/spread-sheets-tablesheet";
import "@grapecity/spread-sheets-designer-resources-cn";
import "@grapecity/spread-sheets-designer";

import demoJson from './demo.json';

export default {
  name: "App",
  data: function () {
    var config = GC.Spread.Sheets.Designer.DefaultConfig;
    //ribbon添加测试菜单:
    config.ribbon.push({
      "id": "test",
      "text": "测试菜单",
      "buttonGroups": [{
        "label": "测试1",
        "thumbnailClass": "button_class",
        "commandGroup": {
          "children": [
            {
              "direction": "vertical",
              "commands": [
                "save1",
                "delete1",
              ]
            }
          ]
        }
      }, {
        "label": "测试2",
        "commandGroup": {
          "children": []
        }
      }],
      // 其他项目内容
      "contextMenu": [
        "designer.insertSignature",
      ],
    });
    //声明菜单事件
    config.commandMap = {
      save1: {
        title: "保存服务器",
        text: "",
        iconClass: "save1",
        bigButton: "true",
        commandName: "save1",
        execute: async (context, propertyName, fontItalicChecked) => {
          // 自定义操作符
          alert(context, propertyName, fontItalicChecked);
        }
      },
      delete1: {
        title: "删除数据",
        text: "",
        iconClass: "delete1",
        bigButton: "true",
        commandName: "delete1",
        execute: async (context, propertyName, fontItalicChecked) => {
          // 自定义操作符
          alert(context, propertyName, fontItalicChecked);
        }
      },
      "designer.insertSignature": {
        text: "Insert Signature",
        commandName: "designer.insertSignature",
        visibleContext: "ClickRowHeader",
        execute:
        // execute_InsertSignature,后面是一个简单的演示代码片段
            () => {
              console.log("Insert Signature");
            }
      }
    }

    return {
      styleInfo: {height: "80vh", width: "50vw"},
      config: config,
      spreadOptions: {
        //表单工具栏的  基本配置
        sheetCount: 2,  //sheet 表格数量
        allowUserZoom: false,  //是否允许缩放
        tabEditable: false,  //tab是否允许编辑
        newTabVisible: false, //新tab是否可见
        showScrollTip: false,
        showVerticalScrollbar: false,
        showHorizontalScrollbar: false,
        allowUserResize: false,
        autoFitType: false,
        allowUserDragDrop: false,  //允许用户拖拽单元格
        allowUserDragMerge: false, //允许用户合并单元格
      },

      changingText: '',
      currentTxt: '',
      sheetJsonStr: '',

      designer: null,
      spread: null,
    };
  },
  methods: {
    designerInitialized(value) {
      this.designer = value;
      this.spread = this.designer.getWorkbook();

      this.spread.suspendPaint();
      let spreadNS = GC.Spread.Sheets;
      let thisObj = this;

      this.spread.bind(spreadNS.Events.SelectionChanging, function (e, args) {
        let selection = args.newSelections.pop();
        let sheetArea = args.sheetArea === 0 ? 'sheetCorner' : args.sheetArea === 1 ?
            'columnHeader' : args.sheetArea === 2 ? 'rowHeader' : 'viewPort';
        thisObj.changingText =
            `事件名称:${GC.Spread.Sheets.Events.SelectionChanging}。` +
            `表单:${args.sheetName}。` +
            `表格区域:${sheetArea}。` +
            `行:${selection.row}。` +
            `列:${selection.col}。` +
            `行数:${selection.rowCount}。` +
            `列数:${selection.colCount}。`;
      });
      this.spread.bind(spreadNS.Events.EditEnded, function (e, args) {
        thisObj.currentTxt = `事件名称:${GC.Spread.Sheets.Events.EditEnded}。` +
            `表单:${args.sheetName}。` +
            `行:${args.row}。` +
            `列:${args.col}。` +
            `文本:${args.editingText}。`;
        console.log(this.currentTxt)
      });
      this.spread.resumePaint();

      // spread.bind(spreadNS.Events.ActiveSheetChanged, function (e, args) {
      //   let eventLog =
      //       'SpreadEvent: ' + GC.Spread.Sheets.Events.ActiveSheetChanged + ' event called' + '\n' +
      //       'oldSheetName: ' + args.oldSheet.name() + '\n' +
      //       'newSheetName: ' + args.newSheet.name();
      //   console.log(eventLog)
      // });

      // spread.bind(spreadNS.Events.CellClick, function (e, args) {
      //   let sheetArea = args.sheetArea === 0 ? 'sheetCorner' : args.sheetArea === 1 ? 'columnHeader' : args.sheetArea === 2 ? 'rowHeader' : 'viewPort';
      //   let eventLog =
      //       'SpreadEvent: ' + GC.Spread.Sheets.Events.CellClick + ' event called' + '\n' +
      //       'sheetArea: ' + sheetArea + '\n' +
      //       'row: ' + args.row + '\n' +
      //       'col: ' + args.col;
      //   console.log(eventLog)
      // });
      // spread.bind(spreadNS.Events.SelectionChanging, function (e, args) {
      //   let selection = args.newSelections.pop();
      //   let sheetArea = args.sheetArea === 0 ? 'sheetCorner' : args.sheetArea === 1 ? 'columnHeader' : args.sheetArea === 2 ? 'rowHeader' : 'viewPort';
      //   let eventLog =
      //       'SpreadEvent: ' + GC.Spread.Sheets.Events.SelectionChanging + ' event called' + '\n' +
      //       'sheetArea: ' + sheetArea + '\n' +
      //       'row: ' + selection.row + '\n' +
      //       'column: ' + selection.col + '\n' +
      //       'rowCount: ' + selection.rowCount + '\n' +
      //       'colCount: ' + selection.colCount;
      //
      //   console.log(eventLog)
      // });
      // spread.bind(spreadNS.Events.SelectionChanged, function (e, args) {
      //   let selection = args.newSelections.pop();
      //   if (selection.rowCount > 1 && selection.colCount > 1) {
      //     let sheetArea = args.sheetArea === 0 ? 'sheetCorner' : args.sheetArea === 1 ? 'columnHeader' : args.sheetArea === 2 ? 'rowHeader' : 'viewPort';
      //     let eventLog =
      //         'SpreadEvent: ' + GC.Spread.Sheets.Events.SelectionChanged + ' event called' + '\n' +
      //         'sheetArea: ' + sheetArea + '\n' +
      //         'row: ' + selection.row + '\n' +
      //         'column: ' + selection.col + '\n' +
      //         'rowCount: ' + selection.rowCount + '\n' +
      //         'colCount: ' + selection.colCount;
      //     console.log(eventLog)
      //   }
      // });
      // spread.bind(spreadNS.Events.EditStarting, function (e, args) {
      //   let eventLog =
      //       'SpreadEvent: ' + GC.Spread.Sheets.Events.EditStarting + ' event called' + '\n' +
      //       'row: ' + args.row + '\n' +
      //       'column: ' + args.col;
      //
      //   console.log(eventLog)
      // });

    },
    toJson() {
      var serializationOption = {
        ignoreFormula: true, //忽略?
        ignoreStyle: true,   //忽略样式
        rowHeadersAsFrozenColumns: true,
        columnHeadersAsFrozenRows: true,
      };

      this.sheetJsonStr = JSON.stringify(this.designer.getWorkbook().toJSON(serializationOption));
      console.log(this.sheetJsonStr)
    },
    fromJson() {
      let jsonOptions = {
        ignoreFormula: false,
        ignoreStyle: false,
        frozenColumnsAsRowHeaders: false,
        frozenRowsAsColumnHeaders: false,
        doNotRecalculateAfterLoad: false,
      };
      //FromJson
      let spread2 = this.designer.getWorkbook();
      spread2.fromJSON(JSON.parse(JSON.stringify(demoJson)), jsonOptions);
    },
  },
}
</script>


<style>

.textarea-container {
  margin: 20px;
  width: calc(100vw - 60vw);
  height: 50px;
  border: 1px solid #000000;
  color: black;
  overflow: auto;
}

.delete1 {
  width: 100px !important;
  height: 20px;
  background: red;
}

.save1 {
  width: 100px !important;
  height: 20px;
  background: blue;
}
</style>

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

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

相关文章

Python之路:网络工程师的自动化进阶(第2版)

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 I. 引言 随着网络技术的不断发展&#xff0c;…

H5向微信小程序发送信息(小程序web-view打开H5)

引入weixin-js-sdk npm i weixin-js-sdk 页面引入 // 引入wxjsimport wx from "weixin-js-sdk"; 点击触发方法 methods: {goweap(id){console.log(wx);// H5传递数据 &#xff08;navigateBack&#xff09;wx.miniProgram.navigateBack({delta: 1});wx.min…

混沌工程的核心原则是什么?

在软件开发和系统运维领域&#xff0c;一种新兴的实践逐渐崭露头角&#xff0c;那就是混沌工程。混沌工程的核心理念是通过有计划的、控制的实验引入混沌&#xff0c;以验证和改善系统的稳健性。本文将介绍混沌工程的定义及核心原则是什么! 什么是混沌工程? 混沌工程是一种系统…

【理论】STM32定时器时间计算公式 +【实践】TIM中断1s计时一次

前言&#xff1a;定时器TIM的详细知识点见我的博文&#xff1a;11.TIM定时中断-CSDN博客 STM32定时器时间计算公式 公式解释&#xff1a; ARR&#xff08;TIM_Period&#xff09;&#xff1a;自动重装载值&#xff0c;是定时器溢出前的计数值 PSC&#xff08;TIM_Prescaler&…

k8s的二进制部署(源码包部署)

实验条件&#xff1a; 主机名 IP地址 组件 作用 master01 20.0.0.17 kube-apiserver、kube-controller-manager、kube-scheduler、etcd k8s部署 master02 20.0.0.27 kube-apiserver、kube-controller-manager、kube-scheduler node01 20.0.0.37 kubelet、kube-pro…

工具系列:TimeGPT_(8)使用不规则时间戳进行时间序列预测

文章目录 介绍不规则时间戳的单变量时间预测不规则时间戳的外生变量时间预测 介绍 在处理时间序列数据时&#xff0c;时间戳的频率是一个关键因素&#xff0c;可以对预测结果产生重大影响。像每日、每周或每月这样的常规频率很容易处理。然而&#xff0c;像工作日这样的不规则…

OpenAPI,已支持表单数据格式校验

OpenAPI 路径 开放平台 功能简介 「OpenAPI」- 支持表单数据格式校验。 通过「OpenAPI-新增表单数据」接口&#xff0c;新增数据时&#xff0c;若数据格式不匹配&#xff0c;会导致无法新增。 例如&#xff0c;数字不能新增到日期格式的表单字段。 请参考数据格式传参&a…

IPv4归属地信息查询方法与应用

IPv4地址归属地信息查询是网络管理和安全领域的关键工具。本文将介绍IPv4地址的概念&#xff0c;探讨IPv4归属地信息的重要性&#xff0c;并详细介绍几种查询IPv4归属地信息的方法以及其应用场景。 第一部分&#xff1a;IPv4地址简介 1.1 什么是IPv4地址 IPv4&#xff08;In…

HTML 网页设计 简约风格 注册界面

成品如下 html <!DOCTYPE html> <html><head><meta charset"utf-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Science科幻注册界面</title><link href"…

游戏服务器列表-增量处理

前言 服务器列表比较简单 固定表/开服表&#xff08;一般只会增加及合并),操作频率很低 一般由 服务器ID IP NAME 开服时间 为什么要自己写个&#xff0c; MySQL的增量备份日志&#xff0c;相对太复杂了 看下 一条UPDATE 语句 随便找了表 修改了 10002 level 1 ->2 得用专门…

uniapp原生插件 - android原生插件打包流程 ( 避坑指南一)

【彩带- 避坑知识点】: 当时开发中安卓插件打包成功后&#xff0c;uniapp引用插件aar&#xff0c;用云打包 &#xff0c;总是提示不包含插件。原因是因为module的androidManifest.xml文件没有注册activity。 这一步 很重要&#xff0c;一定要注册。 --------------------------…

Mybatis枚举类型处理和类型处理器

专栏精选 引入Mybatis Mybatis的快速入门 Mybatis的增删改查扩展功能说明 mapper映射的参数和结果 Mybatis复杂类型的结果映射 Mybatis基于注解的结果映射 文章目录 专栏精选摘要引言正文枚举类型映射简单枚举映射枚举顺序映射复杂枚举映射 类型处理器 总结 摘要 在这篇…

【C++】开源:cpp-httplib HTTP协议库配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍cpp-httplib HTTP协议库配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&a…

vmware虚拟机中Nat、桥接模式和仅主机的差别

NAT 在NAT模式下&#xff0c;主机3是Kali和Win两个操作系统的宿主机&#xff0c;那么Kali和Win可以连接到外网&#xff0c;也可以和主机3进行互联&#xff0c;但是主机1和主机2不能连接到Kali和Win。 桥接 在桥接模式下&#xff0c;主机3是Kali和Win两个操作系统的宿主机&…

PyTorch实战:基于Seq2seq模型处理机器翻译任务(模型预测)

文章目录 引言数据预处理加载字典对象en2id和zh2id文本分词 加载训练好的Seq2Seq模型模型预测完整代码结束语 引言 随着全球化的深入&#xff0c;翻译需求日益增长。传统的人工翻译方式虽然质量高&#xff0c;但效率低&#xff0c;成本高。机器翻译的出现&#xff0c;为解决这…

Windows搭建FTP服务器教学以及计算机端口介绍

目录 一. FTP服务器介绍 FTP服务器是什么意思&#xff1f; 二.Windows Service 2012 搭建FTP服务器 1.开启防火墙 2.创建组 ​编辑3.创建用户 4.用户绑定组 5.安装ftp服务器 ​编辑6.配置ftp服务器 7.配置ftp文件夹的权限 8.连接测试 三.计算机端口介绍 什么是网络…

最新AI系统ChatGPT网站H5系统源码,支持Midjourney绘画,GPT语音对话+ChatFile文档对话总结+DALL-E3文生图

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

12.27_黑马数据结构与算法笔记Java(补1)

目录 266 活动选择问题 分析 267 活动选择问题 贪心 268 分数背包问题 贪心 269 0-1 背包问题 贪心 270 斐波那契 动态规划 271 斐波那契 动态规划 降维 272 Bellman Ford 动态规划 分析 273 Bellman Ford 动态规划 实现1 274 Bellman Ford 动态规划 实现2 275 Leetco…

文献速递:人工智能医学影像分割---一个用于 COVID-19 CT 图像的粗细分割网络

文献速递&#xff1a;人工智能医学影像分割—一个用于 COVID-19 CT 图像的粗细分割网络 01 文献速递介绍 2019 年新型冠状病毒疾病&#xff08;COVID-19&#xff09;正在全球迅速传播。自 2019 年以来&#xff0c;已有超过一千万人感染&#xff0c;其中数十万人死亡。COVID-…

apisix 插件配置 未生效 未起作用

插件配置完成&#xff0c;却没生效&#xff0c;请检查插件的启用状态是否是启用状态&#xff0c; 以某个route配置的限速插件&#xff08;limit-req&#xff09;为例 1.打开dashboad-->路由-->某个路由-->更多-->查看&#xff0c; 查看配置&#xff0c;实际未启用…