diff --git a/BootstrapBlazor.Extensions.sln b/BootstrapBlazor.Extensions.sln index d5ae678a..f062a7e4 100644 --- a/BootstrapBlazor.Extensions.sln +++ b/BootstrapBlazor.Extensions.sln @@ -192,6 +192,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.PdfViewer", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.Vditor", "src\components\BootstrapBlazor.Vditor\BootstrapBlazor.Vditor.csproj", "{D417E1B9-D146-4983-81D0-79F3193B322B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.TouchSocket", "src\extensions\BootstrapBlazor.TouchSocket\BootstrapBlazor.TouchSocket.csproj", "{FD23CEA1-78EB-85D7-8EDF-047657355B52}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.OfficeViewer", "src\components\BootstrapBlazor.OfficeViewer\BootstrapBlazor.OfficeViewer.csproj", "{2436940C-5920-D801-8A81-721F4C20A355}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -522,6 +526,14 @@ Global {D417E1B9-D146-4983-81D0-79F3193B322B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D417E1B9-D146-4983-81D0-79F3193B322B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D417E1B9-D146-4983-81D0-79F3193B322B}.Release|Any CPU.Build.0 = Release|Any CPU + {FD23CEA1-78EB-85D7-8EDF-047657355B52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD23CEA1-78EB-85D7-8EDF-047657355B52}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD23CEA1-78EB-85D7-8EDF-047657355B52}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD23CEA1-78EB-85D7-8EDF-047657355B52}.Release|Any CPU.Build.0 = Release|Any CPU + {2436940C-5920-D801-8A81-721F4C20A355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2436940C-5920-D801-8A81-721F4C20A355}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2436940C-5920-D801-8A81-721F4C20A355}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2436940C-5920-D801-8A81-721F4C20A355}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -612,6 +624,8 @@ Global {08458CA3-BF81-48E8-870D-9389DC037808} = {FF1089BE-C704-4374-B629-C57C08E1798F} {4757B038-70E4-40B0-9B73-700EE5632B07} = {FF1089BE-C704-4374-B629-C57C08E1798F} {D417E1B9-D146-4983-81D0-79F3193B322B} = {FF1089BE-C704-4374-B629-C57C08E1798F} + {FD23CEA1-78EB-85D7-8EDF-047657355B52} = {7B29E81D-92DE-46C8-8EDC-1B48C8F12BC2} + {2436940C-5920-D801-8A81-721F4C20A355} = {FF1089BE-C704-4374-B629-C57C08E1798F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D5EB1960-6F30-4CE1-B375-EAE1F787D6FF} diff --git a/src/components/BootstrapBlazor.OfficeViewer/BootstrapBlazor.OfficeViewer.csproj b/src/components/BootstrapBlazor.OfficeViewer/BootstrapBlazor.OfficeViewer.csproj new file mode 100644 index 00000000..0f96d940 --- /dev/null +++ b/src/components/BootstrapBlazor.OfficeViewer/BootstrapBlazor.OfficeViewer.csproj @@ -0,0 +1,21 @@ + + + + 9.0.0 + + + + Bootstrap Blazor WebAssembly wasm UI Components Office Viewer + Bootstrap UI components extensions of Microsoft Office Documentation Viewer + + + + + + + + + + + + diff --git a/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor b/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor new file mode 100644 index 00000000..c713d001 --- /dev/null +++ b/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor @@ -0,0 +1,5 @@ +@namespace BootstrapBlazor.Components +@inherits BootstrapModuleComponentBase +@attribute [JSModuleAutoLoader("./_content/BootstrapBlazor.OfficeViewer/OfficeViewer.razor.js", JSObjectReference = true, AutoInvokeDispose = false)] + +
diff --git a/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor.cs b/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor.cs new file mode 100644 index 00000000..66b60a85 --- /dev/null +++ b/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor.cs @@ -0,0 +1,109 @@ +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ + +using Microsoft.AspNetCore.Components; + +namespace BootstrapBlazor.Components; + +/// +/// Represents a viewer component for displaying Office documents in a web application. +/// +/// The component allows users to display Office files such as Word, +/// Excel, or PowerPoint documents. It provides configurable options for the document URL, viewer height, and a callback +/// for when the document is loaded. +public partial class OfficeViewer +{ + /// + /// Gets or sets the url for the Office file to be displayed. + /// + [Parameter] + public string? Url { get; set; } + + /// + /// Gets or sets the viewer height. Default is null. + /// + [Parameter] + public string? Height { get; set; } + + /// + /// Gets or sets the document loaded event callback. + /// + [Parameter] + public Func? OnLoaded { get; set; } + + [Inject, NotNull] + private NavigationManager? NavigationManager { get; set; } + + private string? ClassString => CssBuilder.Default("bb-office-viewer-container") + .AddClassFromAttributes(AdditionalAttributes) + .Build(); + + private string? StyleString => CssBuilder.Default() + .AddClass($"--bb-office-viewer-height: {Height};", !string.IsNullOrEmpty(Height)) + .Build(); + + private string? _url; + + /// + /// + /// + /// + /// + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + + if (firstRender) + { + _url = Url; + return; + } + + var rerender = false; + if (_url != Url) + { + _url = Url; + rerender = true; + } + + if (rerender) + { + await InvokeVoidAsync("load", Id, GetAbsoluteUri(_url)); + } + } + + /// + /// + /// + /// + protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, new + { + LoadedCallaback = nameof(TriggerOnLoaded), + Url = GetAbsoluteUri(Url) + }); + + private string GetAbsoluteUri(string? url) + { + url ??= string.Empty; + if (string.IsNullOrEmpty(url)) + { + return url; + } + var uri = NavigationManager.ToAbsoluteUri(url); + return uri.AbsoluteUri; + } + + /// + /// Trigger OnLoaded callback when the PDF document is loaded. + /// + /// + [JSInvokable] + public async Task TriggerOnLoaded() + { + if (OnLoaded != null) + { + await OnLoaded(); + } + } +} diff --git a/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor.js b/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor.js new file mode 100644 index 00000000..0337f9d4 --- /dev/null +++ b/src/components/BootstrapBlazor.OfficeViewer/OfficeViewer.razor.js @@ -0,0 +1,37 @@ +import { addLink } from "../BootstrapBlazor/modules/utility.js" +import Data from "../BootstrapBlazor/modules/data.js" + +export async function init(id, invoke, options) { + await addLink("./_content/BootstrapBlazor.OfficeViewer/office-viewer.css"); + + const el = document.getElementById(id); + const officeViewer = { el, invoke, options }; + Data.set(id, officeViewer); + + await load(id, options.url); +} + +export async function load(id, url) { + const officeViewer = Data.get(id); + const { el, invoke, options } = officeViewer; + + el.innerHTML = ''; + + if (url) { + const { frame } = officeViewer; + const viewer = frame || createFrame(el); + if (options.loadedCallaback) { + viewer.onload = () => { + invoke.invokeMethodAsync(options.loadedCallaback); + }; + } + viewer.src = `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(url)}`; + } +} + +const createFrame = el => { + const frame = document.createElement('iframe'); + frame.classList.add('bb-office-viewer'); + el.appendChild(frame); + return frame; +} diff --git a/src/components/BootstrapBlazor.OfficeViewer/_Imports.razor b/src/components/BootstrapBlazor.OfficeViewer/_Imports.razor new file mode 100644 index 00000000..d46585f8 --- /dev/null +++ b/src/components/BootstrapBlazor.OfficeViewer/_Imports.razor @@ -0,0 +1,2 @@ +@using BootstrapBlazor.Components; +@using Microsoft.AspNetCore.Components.Web diff --git a/src/components/BootstrapBlazor.OfficeViewer/wwwroot/office-viewer.css b/src/components/BootstrapBlazor.OfficeViewer/wwwroot/office-viewer.css new file mode 100644 index 00000000..0cdbffd0 --- /dev/null +++ b/src/components/BootstrapBlazor.OfficeViewer/wwwroot/office-viewer.css @@ -0,0 +1,9 @@ +.bb-office-viewer-container { + width: 100%; + height: var(--bb-office-viewer-height, 500px); +} + +.bb-office-viewer { + width: 100%; + height: 100%; +}