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>