diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj index 4badaa064fb..cd163e942ae 100644 --- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj +++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj @@ -38,12 +38,12 @@ - + - + @@ -64,6 +64,7 @@ + diff --git a/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor b/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor new file mode 100644 index 00000000000..0ce64a216f8 --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor @@ -0,0 +1,33 @@ +@page "/univer-sheet" +@inherits WebSiteModuleComponentBase +@attribute [JSModuleAutoLoader("Samples/UniverSheets.razor.js")] + +

@Localizer["UniverSheetTitle"]

+ +

@Localizer["UniverSheetIntro"]

+ + + + +
+

@((MarkupString)Localizer["NormalDesc1"].Value)

+ +
+
+ +
+
+ + +
+

@((MarkupString)Localizer["NormalDesc2"].Value)

+ +
+
+ +
+
diff --git a/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.cs new file mode 100644 index 00000000000..2c39bceac4b --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License +// See the LICENSE file in the project root for more information. +// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone + +namespace BootstrapBlazor.Server.Components.Samples; + +/// +/// UniverSheet 组件示例代码 +/// +public partial class UniverSheets +{ + [Inject, NotNull] + private ToastService? ToastService { get; set; } + + [Inject, NotNull] + private IStringLocalizer? Localizer { get; set; } + + private readonly Dictionary Plugins = new() + { + { "ReportPlugin", "univer-sheet/plugin.js" } + }; + + private UniverSheet _sheetExcel = default!; + + private UniverSheet _sheetPlugin = default!; + + private async Task OnReadyAsync() => await ToastService.Information(Localizer["ToastOnReadyTitle"], Localizer["ToastOnReadyContent"]); + + private static Task OnPostDataAsync(UniverSheetData data) + { + // 这里可以根据 data 的内容进行处理然后返回处理后的数据 + // 本例返回与时间相关的数据 + var result = new UniverSheetData() + { + MessageName = data.MessageName, + CommandName = data.CommandName, + Data = new + { + key = "datetime", + Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + } + }; + return Task.FromResult(result); + } + + private async Task OnPushExcelData() + { + await _sheetExcel.PushDataAsync(new UniverSheetData() + { + MessageName = "MessageName", + CommandName = "CommandName", + Data = new object[] + { + new object[] { "1", "2", "3", "4", "5" }, + new object[] { "1", "2", "3", "4", "5" }, + } + }); + } + + private async Task OnPushPluginData() + { + await _sheetPlugin.PushDataAsync(new UniverSheetData() + { + MessageName = "MessageName", + CommandName = "CommandName", + Data = new + { + Id = "1", + Name = "Test", + Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + } + }); + } +} diff --git a/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.css b/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.css new file mode 100644 index 00000000000..abfb32681bb --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.css @@ -0,0 +1,5 @@ +.bb-sheet-demo { + height: 290px; + width: 100%; + border: 1px solid var(--bs-border-color); +} diff --git a/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.js b/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.js new file mode 100644 index 00000000000..76d916f6661 --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/UniverSheets.razor.js @@ -0,0 +1,7 @@ +export function init(id) { + +} + +export function dispose(id) { + +} diff --git a/src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs b/src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs index 00297b76b1a..6d7b7c13b0c 100644 --- a/src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs +++ b/src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs @@ -766,6 +766,12 @@ void AddData(DemoMenuItem item) Url = "typed" }, new() + { + IsNew = true, + Text = Localizer["UniverSheet"], + Url = "univer-sheet" + }, + new() { Text = Localizer["VideoPlayer"], Url = "video-player" diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index ba0a648598f..16a5e91b0a6 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -4855,7 +4855,8 @@ "Affix": "Affix", "Watermark": "Watermark", "OctIcon": "Oct Icons", - "Typed": "Typed" + "Typed": "Typed", + "UniverSheet": "UniverSheet" }, "BootstrapBlazor.Server.Components.Samples.Table.TablesHeader": { "TablesHeaderTitle": "Header grouping function", @@ -7002,5 +7003,18 @@ "Html2ImageElementIntro": "Get the base64-encoded image by calling the GetDataAsync method", "Html2ImageButtonText": "Image", "Html2ImageDesc": "Since the underlying library is html-to-image, if you encounter any problems during actual use, please refer to the project Issue" + }, + "BootstrapBlazor.Server.Components.Samples.UniverSheets": { + "UniverSheetTitle": "UniverSheet", + "UniverSheetIntro": "Encapsulates the core spreadsheet component of the open source office suite ​Univer​, providing a high-performance, scalable online spreadsheet solution", + "NormalTitle": "Basic usage", + "NormalIntro": "Set your own plugins by setting the Plugins parameter", + "NormalDesc1": "Push data to the spreadsheet by calling the instance method PushDataAsync", + "NormalDesc2": "Click the Push Data button to push data to the table, and click the first icon on the Toolbar to get data from the server.", + "PushButtonText": "Push", + "ToastOnReadyTitle": "Notification", + "ToastOnReadyContent": "The sheet is ready for push data.", + "PluginTitle": "Plugins", + "PluginIntro": "Set custom plugins by setting the Plugins parameter" } } diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index ec38247ee4d..daf1d0cdb67 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -4855,7 +4855,8 @@ "Affix": "固钉组件 Affix", "Watermark": "水印组件 Watermark", "OctIcon": "Oct Icons", - "Typed": "打字机效果 Typed" + "Typed": "打字机效果 Typed", + "UniverSheet": "表格组件 UniverSheet" }, "BootstrapBlazor.Server.Components.Samples.Table.TablesHeader": { "TablesHeaderTitle": "表头分组功能", @@ -6990,7 +6991,7 @@ "BootstrapBlazor.Server.Components.Samples.Typeds": { "TypedTitle": "Typed 打字机效果", "TypedIntro": "输入任意字符串,它会按照你设置的速度输入,输入的内容会退格,然后根据你设置的字符串数量开始一个新句子。", - "NormalTitle": "Text", + "NormalTitle": "基础用法", "NormalIntro": "通过设置 Text 参数设置要显示的文本", "TypedOptionsTitle": "TypedOptions", "TypedOptionsIntro": "通过设置 TypedOptions 参数的属性自定义打字速度、延时等设定" @@ -7002,5 +7003,18 @@ "Html2ImageElementIntro": "通过调用 GetDataAsync 方法获得 base64-encoded 图片", "Html2ImageButtonText": "Image", "Html2ImageDesc": "由于底层使用的是 html-to-image 实际使用过程中遇到问题请参考项目 Issue" + }, + "BootstrapBlazor.Server.Components.Samples.UniverSheets": { + "UniverSheetTitle": "UniverSheet 电子表格组件", + "UniverSheetIntro": "封装开源办公套件 ​Univer​ 的核心电子表格组件,提供高性能、可扩展的在线表格解决方案", + "NormalTitle": "基础用法", + "NormalIntro": "通过调用实例方法 PushDataAsync 推送数据到电子表格", + "NormalDesc1": "点击 推送数据 按钮主动将数据推送给表格", + "NormalDesc2": "点击 推送数据 按钮主动将数据推送给表格,点击 工具栏 第一个小按钮主动从服务器端获取数据", + "PushButtonText": "推送数据", + "ToastOnReadyTitle": "组件通知", + "ToastOnReadyContent": "表格组件已就绪,可进行后续数据推送等操作", + "PluginTitle": "自定义插件", + "PluginIntro": "通过设置 Plugins 参数设置自己的插件" } } diff --git a/src/BootstrapBlazor.Server/docs.json b/src/BootstrapBlazor.Server/docs.json index 6cbcfd80e9f..2eb67ad658b 100644 --- a/src/BootstrapBlazor.Server/docs.json +++ b/src/BootstrapBlazor.Server/docs.json @@ -226,7 +226,8 @@ "smiles-drawer": "SmilesDrawers", "affix": "Affixs", "watermark": "Watermarks", - "typed": "Typeds" + "typed": "Typeds", + "univer-sheet": "UniverSheets" }, "video": { "table": "BV1ap4y1x7Qn?p=1", diff --git a/src/BootstrapBlazor.Server/wwwroot/univer-sheet/controller.js b/src/BootstrapBlazor.Server/wwwroot/univer-sheet/controller.js new file mode 100644 index 00000000000..a41c049fd0b --- /dev/null +++ b/src/BootstrapBlazor.Server/wwwroot/univer-sheet/controller.js @@ -0,0 +1,117 @@ +import DataService from '../_content/BootstrapBlazor.UniverSheet/data-service.js' + +const { Disposable, setDependencies, Injector, ICommandService, CommandType, UniverInstanceType } = UniverCore; +const { ContextMenuGroup, ContextMenuPosition, RibbonStartGroup, ComponentManager, IMenuManagerService, MenuItemType, getMenuHiddenObservable } = UniverUi; + +const GetDataOperation = { + id: 'report.operation.add-table', + type: CommandType.OPERATION, + handler: async (accessor) => { + const dataService = accessor.get(DataService.name); + const data = await dataService.getDataAsync({ + messageName: "getDataMessage", + commandName: "getDataCommand" + }); + if (data) { + const univerAPI = dataService.getUniverSheet().univerAPI; + const range = univerAPI.getActiveWorkbook().getActiveSheet().getRange(0, 0, 2, 1) + const defaultData = [ + [{ v: data.data.key }], + [{ v: data.data.value }] + ] + range.setValues(defaultData); + } + } +}; + +function GetDataIcon() { + return React.createElement( + 'svg', + { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", viewBox: "0 0 24 24" }, + React.createElement( + 'path', + { fill: "currentColor", d: "M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m.16 14a6.981 6.981 0 0 0-5.147 2.256A7.966 7.966 0 0 0 12 20a7.97 7.97 0 0 0 5.167-1.892A6.979 6.979 0 0 0 12.16 16M12 4a8 8 0 0 0-6.384 12.821A8.975 8.975 0 0 1 12.16 14a8.972 8.972 0 0 1 6.362 2.634A8 8 0 0 0 12 4m0 1a4 4 0 1 1 0 8a4 4 0 0 1 0-8m0 2a2 2 0 1 0 0 4a2 2 0 0 0 0-4" } + ) + ); +} + +function ReportGetDataFactory(accessor) { + return { + id: GetDataOperation.id, + type: MenuItemType.BUTTON, + icon: 'GetDataIcon', + tooltip: '获取数据', + title: '获取数据', + hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET) + }; +} + +export class ReportController extends Disposable { + constructor(_injector, _commandService, _menuManagerService, _componentManager) { + super(); + + this._injector = _injector; + this._commandService = _commandService; + this._menuManagerService = _menuManagerService; + this._componentManager = _componentManager; + + this._initCommands(); + this._registerComponents(); + this._initMenus(); + this._registerReceiveDataCallback(); + } + + _registerReceiveDataCallback() { + const dataService = this._injector.get(DataService.name); + dataService.registerReceiveDataCallback(data => { + this.receiveData(data, dataService.getUniverSheet()); + }); + } + + _initCommands() { + [GetDataOperation].forEach((c) => { + this.disposeWithMe(this._commandService.registerCommand(c)); + }); + } + + _registerComponents() { + const componentMap = { + GetDataIcon, + } + Object.entries(componentMap).forEach((item) => { + this.disposeWithMe(this._componentManager.register(...item)); + }); + + } + + _initMenus() { + this._menuManagerService.mergeMenu({ + [RibbonStartGroup.HISTORY]: { + [GetDataOperation.id]: { + order: -1, + menuItemFactory: ReportGetDataFactory + }, + }, + [ContextMenuPosition.MAIN_AREA]: { + [ContextMenuGroup.DATA]: { + [GetDataOperation.id]: { + order: 0, + menuItemFactory: ReportGetDataFactory + } + } + } + }); + } + + receiveData(data, sheet) { + const { univerAPI } = sheet; + const range = univerAPI.getActiveWorkbook().getActiveSheet().getRange(0, 0, 2, 3) + const defaultData = [ + [{ v: 'Id' }, { v: 'Name' }, { v: 'Value' }], + [{ v: data.data.id }, { v: data.data.name }, { v: data.data.value }] + ] + range.setValues(defaultData); + } +} + +setDependencies(ReportController, [Injector, ICommandService, IMenuManagerService, ComponentManager]); diff --git a/src/BootstrapBlazor.Server/wwwroot/univer-sheet/plugin.js b/src/BootstrapBlazor.Server/wwwroot/univer-sheet/plugin.js new file mode 100644 index 00000000000..81e97a14e3b --- /dev/null +++ b/src/BootstrapBlazor.Server/wwwroot/univer-sheet/plugin.js @@ -0,0 +1,31 @@ +import DataService from '../_content/BootstrapBlazor.UniverSheet/data-service.js' +import { ReportController } from './controller.js' + +const { Plugin, Injector, setDependencies } = UniverCore; + +// 定义插件类 +export class ReportPlugin extends Plugin { + static pluginName = 'ReportPlugin'; + + constructor(_injector) { + super(); + + this._injector = _injector; + } + + onStarting() { + this._injector.add([ReportController]); + this._injector.add([DataService.name, { useClass: DataService }]) + } + + onReady() { + this._injector.get(ReportController) + } + + onRendered() { + + } +} + +// 设置依赖 +setDependencies(ReportPlugin, [Injector]);