一、Univer介紹
Univer 是 Office 系列辦公套件的開源替代品,包括電子表格、文檔和幻燈片。目前提供公式、數(shù)字格式、條件格式、數(shù)據(jù)驗證、圖文混排等功能。你可以將 Univer 集成到你的系統(tǒng)當中,并基于 Univer 開發(fā)個性化的業(yè)務需求。
二、使用步驟
1、使用UMD
<scriptsrc="https://unpkg.com/@univerjs/umd/lib/univer.full.umd.js"></script> <linkrel="stylesheet"href="https://unpkg.com/@univerjs/umd/lib/univer.css">
將上邊兩個鏈接復制到瀏覽器打開,另存為進行下載到本地
引入到publish/index.html中
組件內使用
<template>
<div ref="sheetContainer" style="height: 100%"></div>
</template>
<script setup>
const {
UniverCore,
UniverDesign,
UniverEngineRender,
UniverEngineFormula,
UniverDocs,
UniverDocsUi,
UniverUi,
UniverSheets,
UniverSheetsUi,
UniverSheetsNumfmt,
UniverSheetsFormula,
UniverFacade,
} = window;
const props = defineProps({
data: {
type: Object,
default: () => ({}),
},
});
const univerRef = ref(null);
const workbook = ref(null);
const sheetContainer = ref(null);
const univerAPI = ref(null);
const init = (data) => {
const univer = new UniverCore.Univer({
theme: UniverDesign.defaultTheme,
});
univerRef.value = univer;
univer.registerPlugin(UniverEngineRender.UniverRenderEnginePlugin);
univer.registerPlugin(UniverEngineFormula.UniverFormulaEnginePlugin);
univer.registerPlugin(UniverUi.UniverUIPlugin, {
container: sheetContainer.value,
});
univer.registerPlugin(UniverDocs.UniverDocsPlugin, {
hasScroll: false,
});
univer.registerPlugin(UniverDocsUi.UniverDocsUIPlugin);
univer.registerPlugin(UniverSheets.UniverSheetsPlugin);
univer.registerPlugin(UniverSheetsUi.UniverSheetsUIPlugin);
univer.registerPlugin(UniverSheetsNumfmt.UniverSheetsNumfmtPlugin);
univer.registerPlugin(UniverSheetsFormula.UniverSheetsFormulaPlugin);
workbook.value = univer.createUniverSheet(data);
univerAPI.value = UniverFacade.FUniver.newAPI(univer);
};
onMounted(() => {
init(props.data);
});
const getData = () => {
if (!workbook.value) {
throw new Error('Workbook is not initialized');
}
return workbook.value.save();
};
defineExpose({
getData,
univerAPI: univerAPI.value,
});
</script>
2、npm安裝
npm install @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-ui @univerjs/ui
npm install @univerjs/facade
三、表格數(shù)據(jù)結構
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var { UniverCore } = window;
/**
* Default workbook data
* @type {IWorkbookData} document see https://univer.work/api/core/interfaces/IWorkbookData.html
*/
export const DEFAULT_WORKBOOK_DATA = {
id: 'workbook-01',
locale: UniverCore.LocaleType.ZH_CN,
name: 'universheet',
sheetOrder: ['sheet-01', 'sheet-02', 'sheet-03'],
appVersion: '3.0.0-alpha',
sheets: {
'sheet-01': {
type: UniverCore.SheetTypes.GRID,
id: 'sheet-01',
cellData: {
0: {
0: {
v: 'Hello World',
},
},
},
name: 'sheet1',
tabColor: 'red',
hidden: UniverCore.BooleanNumber.FALSE,
rowCount: 1000,
columnCount: 20,
zoomRatio: 1,
scrollTop: 200,
scrollLeft: 100,
defaultColumnWidth: 93,
defaultRowHeight: 27,
status: 1,
showGridlines: 1,
hideRow: [],
hideColumn: [],
rowHeader: {
width: 46,
hidden: UniverCore.BooleanNumber.FALSE,
},
columnHeader: {
height: 20,
hidden: UniverCore.BooleanNumber.FALSE,
},
selections: ['A2'],
rightToLeft: UniverCore.BooleanNumber.FALSE,
pluginMeta: {},
},
'sheet-02': {
type: UniverCore.SheetTypes.GRID,
id: 'sheet-02',
name: 'sheet2',
cellData: {},
},
'sheet-03': {
type: UniverCore.SheetTypes.GRID,
id: 'sheet-03',
name: 'sheet3',
cellData: {},
},
},
};
四、API
// 獲取當前表數(shù)據(jù)
const activeSheet = univerAPI.getActiveWorkbook().getActiveSheet()
// 設置單元格 value
const range = activeSheet.getRange(0, 0)
if (!range) {
throw new Error('range is not defined')
}
range.setValue(value)
// 設置某個范圍單元格數(shù)據(jù)
const values = [
['Hello', 'World!'],
['Hello', 'Univer!'],
]
const range = activeSheet.getRange(0, 0, values.length, values[0].length)
// getRange對應的從第0行第0列,到第X行,第X列(索引0開始)
if (!range)
throw new Error('range is not defined')
range.setValues(values)
// 獲取某個單元格value =>getRange=>第X行,第X列, 到 到第X行,第X列(索引0開始)
const range = activeSheet.getRange(0, 0, 2, 2)
if (!range)
throw new Error('range is not defined')
const data = []
range.forEach((row, col, cell) => {
data[row] = data[row] || []
data[row][col] = cell.v?.toString()
})
// 獲取workbookData 和傳入的數(shù)據(jù)格式一致
const activeWorkbook = univerAPI.getActiveWorkbook()
console.log(JSON.stringify(activeWorkbook.getSnapshot(), null, 2))
// 獲取sheetData 數(shù)據(jù) -> 是獲取workbookData中的sheet中的data
const activeWorkbook = univerAPI.getActiveWorkbook()
if (!activeWorkbook)
throw new Error('activeWorkbook is not defined')
const snapshot = activeWorkbook.getSnapshot()
const sheet1 = Object.values(snapshot.sheets).find((sheet) => {
return sheet.id === 'sheet-01'
})
// 創(chuàng)建sheet
const activeWorkbook = univerAPI.getActiveWorkbook()
const sheet = activeWorkbook.create('Sheet2', 10, 10) // 設置10行10列表格
// scroll to B100
const activeWorkbook = univerAPI.getActiveWorkbook()
univerAPI.executeCommand('sheet.command.scroll-to-cell', {
range: {
// top 設置 0 0
startColumn: 1,
startRow: 99,
},
})
// scroll to bottom
const { rowCount } = activeSheet._worksheet.getSnapshot()
univerAPI.executeCommand('sheet.command.scroll-to-cell', {
range: {
startColumn: 0,
startRow: rowCount - 1,
},
})
// 設置單元格背景
const range = activeSheet.getRange(0, 0, 1, 1)
range?.setBackgroundColor('red')
// 聚焦單元格
const subUnitId = activeSheet._worksheet.getSheetId()
univerAPI.executeCommand('sheet.operation.set-selections', {
selections: [{
range: {
startRow: 0,
startColumn: 0,
endRow: 0,
endColumn: 0,
rangeType: 0,
},
}],
subUnitId,
unitId: activeWorkbook.getId(),
type: 2,
})
// 清除A1 styles
const subUnitId = activeSheet._worksheet.getSheetId()
await univerAPI.executeCommand('sheet.operation.set-selections', {
selections: [{
range: {
startRow: 0,
startColumn: 0,
endRow: 0,
endColumn: 0,
rangeType: 0,
},
}],
subUnitId,
unitId: activeWorkbook.getId(),
type: 2,
})
univerAPI.executeCommand('sheet.command.clear-selection-format')
五、案例應用:univer在線協(xié)同表格
使用node.js搭建websorket
后端代碼:
//創(chuàng)建一個WebSocket服務器,在8080端口啟動
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8089 });
// 監(jiān)聽前端連接websocket(ws.on的connection事件)
server.on('connection', function connection(ws, req) {
const ip = req.socket.remoteAddress;
const port = req.socket.remotePort;
const clientName = ip + port;
console.log('%s is connected ', clientName);
});
//只要有WebSocket連接到該服務器,就會觸發(fā)'connection'事件;req對象可以用來獲取客戶端的信息,如ip、端口號
//獲取所有已連接的客戶端信息,則可以使用server.clients數(shù)據(jù)集
// 服務器接收數(shù)據(jù)(ws.on的message事件)
module.exports.listener = () => {
server.on('connection', (ws, req) => {
console.log('有客戶端連接成功了', ws, req);
// 對客戶端的連接對象進行message事件的監(jiān)聽
// 當客戶端有消息發(fā)送給服務器時,服務器就能夠觸發(fā)該消息
// msg:由客戶端發(fā)給服務端的數(shù)據(jù)
ws.on('message', (msg = {}) => {
console.log('客戶端發(fā)送給服務器端', msg);
// 當接收到客戶端傳的參數(shù)之后服務器端可以執(zhí)行某些操作(具體看需求)
// 小編這里是做了一個數(shù)據(jù)返回給客戶端
// 是當客戶端連接成功之后會發(fā)送一條信息告訴服務器,服務器監(jiān)聽到信息之后再返回數(shù)據(jù)給客戶端
// 由服務端往客戶端發(fā)送數(shù)據(jù)
server.clients.forEach((client) => {
console.log(client, 'client');
// client.send(JSON.stringify(info));
client.send(msg);
});
});
});
};
前端代碼:
<template>
<div>
<div id="univerContainer" style="height: 500px"></div>
</div>
</template>
<script setup>
var {
UniverCore,
UniverDesign,
UniverEngineRender,
UniverEngineFormula,
UniverDocs,
UniverDocsUi,
UniverUi,
UniverSheets,
UniverSheetsUi,
UniverSheetsNumfmt,
UniverSheetsFormula,
UniverFacade,
} = window;
var univer = new UniverCore.Univer({
theme: UniverDesign.defaultTheme,
});
univer.registerPlugin(UniverEngineRender.UniverRenderEnginePlugin);
univer.registerPlugin(UniverEngineFormula.UniverFormulaEnginePlugin);
univer.registerPlugin(UniverUi.UniverUIPlugin, {
container: 'univerContainer',
});
univer.registerPlugin(UniverDocs.UniverDocsPlugin, {
hasScroll: false,
});
univer.registerPlugin(UniverDocsUi.UniverDocsUIPlugin);
univer.registerPlugin(UniverSheets.UniverSheetsPlugin);
univer.registerPlugin(UniverSheetsUi.UniverSheetsUIPlugin);
univer.registerPlugin(UniverSheetsNumfmt.UniverSheetsNumfmtPlugin);
univer.registerPlugin(UniverSheetsFormula.UniverSheetsFormulaPlugin);
univer.createUniverSheet({
id: 'univer-1',
sheets: {
'sheet-01': {
id: 'sheet-01',
name: 'sheet1',
cellData: {},
},
},
});
const univerAPI = UniverFacade.FUniver.newAPI(univer);
const ws = univerAPI.createSocket('ws://localhost:8089');
ws.open$.subscribe(() => {
console.log('websocket opened');
// ws.send('hello')
});
ws.message$.subscribe((message) => {
console.log('websocket message', JSON.parse(message.data));
const content = JSON.parse(message.data);
console.log('content', content);
const { command, options } = content;
const { id, params } = command;
console.log(params, 'params--------');
// 接受到協(xié)同數(shù)據(jù),本地落盤
univerAPI.executeCommand(id, params, options);
});
ws.close$.subscribe(() => {
console.log('websocket closed');
});
ws.error$.subscribe((error) => {
console.log('websocket error', error);
});
univerAPI.onCommandExecuted((command, options) => {
// 僅同步本地 mutation
if (
command.type !== 2 ||
options?.fromCollab ||
options?.onlyLocal ||
command.id === 'doc.mutation.rich-text-editing'
) {
return;
}
const commandInfo = JSON.stringify({
command,
options: { fromCollab: true },
});
console.log(commandInfo, 'commandInfo');
ws.send(commandInfo);
});
</script>
注意:必須指定id才能協(xié)同
univer.createUniverSheet({
id: 'univer-1',
sheets: {
'sheet-01': {
id: 'sheet-01',
name: 'sheet1',
cellData: {},
},
},
});
————————————————
版權聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權協(xié)議,轉載請附上原文出處鏈接和本聲明。
原文鏈接:https://blog.csdn.net/m0_73884922/article/details/139971295
該文章在 2024/7/25 12:02:14 編輯過