Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<PackageReference Include="BootstrapBlazor.FontAwesome" Version="9.0.2" />
<PackageReference Include="BootstrapBlazor.Gantt" Version="9.0.2" />
<PackageReference Include="BootstrapBlazor.Holiday" Version="9.0.1" />
<PackageReference Include="BootstrapBlazor.Html2Image" Version="9.0.0-beta02" />
<PackageReference Include="BootstrapBlazor.Html2Pdf" Version="9.0.2" />
<PackageReference Include="BootstrapBlazor.IconPark" Version="9.0.2" />
<PackageReference Include="BootstrapBlazor.ImageCropper" Version="9.0.0" />
Expand Down
23 changes: 14 additions & 9 deletions src/BootstrapBlazor.Server/Components/Samples/Html2Images.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,24 @@

<h4>@Localizer["Html2ImageIntro"]</h4>

<PackageTips Name="BootstrapBlazor.Html2Image" />

<DemoBlock Title="@Localizer["Html2ImageElementTitle"]" Introduction="@Localizer["Html2ImageElementIntro"]" Name="Normal">
<section ignore>
<div>@((MarkupString)Localizer["Html2ImageDesc"].Value)</div>
</section>
<Button OnClickWithoutRender="OnExportAsync" Text="@Localizer["Html2ImageButtonText"]" Icon="fa-solid fa-image"></Button>
<Table TItem="Foo" Items="@Items.Take(3)" Id="table-9527">
<TableColumns>
<TableColumn @bind-Field="@context.DateTime" Width="180" />
<TableColumn @bind-Field="@context.Name" Sortable="true" Filterable="true" />
<TableColumn @bind-Field="@context.Address" />
<TableColumn @bind-Field="@context.DateTime" Width="180"/>
<TableColumn @bind-Field="@context.Name" Sortable="true" Filterable="true"/>
<TableColumn @bind-Field="@context.Address"/>
</TableColumns>
</Table>
@if (!string.IsNullOrEmpty(_imageData))
{
<section ignore>
<img src="@_imageData" class="w-100" />
</section>
}
<section ignore>
@if (!string.IsNullOrEmpty(_imageData))
{
<img src="@_imageData" class="w-100"/>
}
</section>
</DemoBlock>
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,7 @@ protected override void OnInitialized()

private async Task OnExportAsync()
{
_imageData = await Html2ImageService.GetDataAsync("#table-9527", new Html2ImageOptions()
{
//IncludeStyleProperties = [
// $"{NavigationManager.BaseUri}_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css",
// $"{NavigationManager.BaseUri}_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css",
// $"{NavigationManager.BaseUri}BootstrapBlazor.Server.styles.css",
// $"{NavigationManager.BaseUri}css/site.css"
//]
});
_imageData = await Html2ImageService.GetDataAsync("#table-9527");
StateHasChanged();

//if (stream != null)
//{
// var reader = new StreamReader(stream);
// var data = await reader.ReadToEndAsync();
// reader.Close();
//}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ public static IServiceCollection AddBootstrapBlazorServices(this IServiceCollect
// 增加 Html2Pdf 导出服务
services.AddBootstrapBlazorHtml2PdfService();

// 增加 Html2Image 导出服务
services.AddBootstrapBlazorHtml2ImageService();

// 增加 WinBox 弹窗服务
services.AddBootstrapBlazorWinBoxService();

Expand Down
5 changes: 3 additions & 2 deletions src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -6993,9 +6993,10 @@
},
"BootstrapBlazor.Server.Components.Samples.Html2Images": {
"Html2ImageTitle": "Html to Image",
"Html2ImageIntro": "Convert any area of ​​the web page into an image service",
"Html2ImageIntro": "Convert any area web page into an image service",
"Html2ImageElementTitle": "ToPng",
"Html2ImageElementIntro": "Get the <b>base64-encoded</b> image by calling the <code>GetDataAsync</code> method",
"Html2ImageButtonText": "Image"
"Html2ImageButtonText": "Image",
"Html2ImageDesc": "Since the underlying library is <a href=\"https://github.com/bubkoo/html-to-image?wt.mc_id=DT-MVP-5004174\" target=\"_blank\">html-to-image</a>, if you encounter any problems during actual use, please refer to the project <a href=\"https://github.com/bubkoo/html-to-image/issues?wt.mc_id=DT-MVP-5004174\" target=\"_blank\">Issue</a>"
}
}
3 changes: 2 additions & 1 deletion src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -6996,6 +6996,7 @@
"Html2ImageIntro": "将网页中任意区域内容转化成图片服务",
"Html2ImageElementTitle": "ToPng",
"Html2ImageElementIntro": "通过调用 <code>GetDataAsync</code> 方法获得 <b>base64-encoded</b> 图片",
"Html2ImageButtonText": "Image"
"Html2ImageButtonText": "Image",
"Html2ImageDesc": "由于底层使用的是 <a href=\"https://github.com/bubkoo/html-to-image?wt.mc_id=DT-MVP-5004174\" target=\"_blank\">html-to-image</a> 实际使用过程中遇到问题请参考项目 <a href=\"https://github.com/bubkoo/html-to-image/issues?wt.mc_id=DT-MVP-5004174\" target=\"_blank\">Issue</a>"
}
}
2 changes: 1 addition & 1 deletion src/BootstrapBlazor.Server/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"group-box": "GroupBoxes",
"handwritten": "Handwrittens",
"html-renderer": "HtmlRenderers",
"html2images": "Html2Images",
"html2image": "Html2Images",
"html2pdf": "Html2Pdfs",
"label": "Labels",
"layout": "Layouts",
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/BootstrapBlazor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>9.3.1-beta31</Version>
<Version>9.3.1-beta32</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
20 changes: 0 additions & 20 deletions src/BootstrapBlazor/Options/Html2ImageOptions.cs

This file was deleted.

54 changes: 5 additions & 49 deletions src/BootstrapBlazor/Services/DefaultHtml2ImageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,22 @@
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone

using Microsoft.Extensions.Logging;

namespace BootstrapBlazor.Components;

/// <summary>
/// 默认 Html to Image 实现
/// <param name="runtime"></param>
/// <param name="logger"></param>
/// 默认 Html2Image 实现
/// </summary>
class DefaultHtml2ImageService(IJSRuntime runtime, ILogger<DefaultHtml2ImageService> logger) : IHtml2Image
class DefaultHtml2ImageService : IHtml2Image
{
private JSModule? _jsModule;
private const string ErrorMessage = "请增加依赖包 BootstrapBlazor.Html2Image 通过 AddBootstrapBlazorHtml2ImageService 进行服务注入; Please add BootstrapBlazor.Html2Image package and use AddBootstrapBlazorHtml2ImageService inject service";

/// <summary>
/// <inheritdoc/>
/// </summary>
public Task<string?> GetDataAsync(string selector, Html2ImageOptions options) => Execute(selector, "toPng", options);
public Task<string?> GetDataAsync(string selector, IHtml2ImageOptions? options = null) => throw new NotImplementedException(ErrorMessage);

/// <summary>
/// <inheritdoc/>
/// </summary>
public Task<Stream?> GetStreamAsync(string selector, Html2ImageOptions options) => ToBlob(selector, options);

private async Task<string?> Execute(string selector, string methodName, Html2ImageOptions options)
{
string? data = null;
try
{
_jsModule ??= await runtime.LoadModuleByName("html2image");
if (_jsModule != null)
{
data = await _jsModule.InvokeAsync<string?>("execute", selector, methodName, options);
}
}
catch (Exception ex)
{
logger.LogError(ex, "{Execute} throw exception", nameof(Execute));
}
return data;
}

private async Task<Stream?> ToBlob(string selector, Html2ImageOptions options)
{
Stream? data = null;
try
{
_jsModule ??= await runtime.LoadModuleByName("html2image");
if (_jsModule != null)
{
var streamRef = await _jsModule.InvokeAsync<IJSStreamReference>("execute", selector, "toBlob", options);
if (streamRef != null)
{
data = await streamRef.OpenReadStreamAsync(streamRef.Length);
}
}
}
catch (Exception ex)
{
logger.LogError(ex, "{ToBlob} throw exception", nameof(ToBlob));
}
return data;
}
public Task<Stream?> GetStreamAsync(string selector, IHtml2ImageOptions? options = null) => throw new NotImplementedException(ErrorMessage);
}
4 changes: 2 additions & 2 deletions src/BootstrapBlazor/Services/IHtml2Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ public interface IHtml2Image
/// </summary>
/// <param name="selector">选择器</param>
/// <param name="options"></param>
Task<string?> GetDataAsync(string selector, Html2ImageOptions options);
Task<string?> GetDataAsync(string selector, IHtml2ImageOptions? options = null);

/// <summary>
/// Export method
/// </summary>
/// <param name="selector">选择器</param>
/// <param name="options"></param>
Task<Stream?> GetStreamAsync(string selector, Html2ImageOptions options);
Task<Stream?> GetStreamAsync(string selector, IHtml2ImageOptions? options = null);
}
60 changes: 60 additions & 0 deletions src/BootstrapBlazor/Services/IHtml2ImageOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// 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([email protected]) Website: https://www.blazor.zone

namespace BootstrapBlazor.Components;

/// <summary>
/// IHtml2ImageOptions 选项类接口
/// </summary>
public interface IHtml2ImageOptions
{
/// <summary>
/// Width in pixels to be applied to node before rendering.
/// </summary>
int? Width { get; set; }

/// <summary>
/// Height in pixels to be applied to node before rendering.
/// </summary>
int? Height { get; set; }

/// <summary>
/// A string value for the background color, any valid CSS color value.
/// </summary>
string? BackgroundColor { get; set; }

/// <summary>
/// Width in pixels to be applied to canvas on export.
/// </summary>
int? CanvasWidth { get; set; }

/// <summary>
/// Height in pixels to be applied to canvas on export.
/// </summary>
int? CanvasHeight { get; set; }

/// <summary>
/// An array of style properties to be copied to node's style before rendering.
/// For performance-critical scenarios, users may want to specify only the required properties instead of all styles.
/// </summary>
string[]? IncludeStyleProperties { get; set; }

/// <summary>
/// A number between `0` and `1` indicating image quality (e.g. 0.92 => 92%)
/// of the JPEG image.
/// </summary>
double? Quality { get; set; }

/// <summary>
/// The pixel ratio of captured image. Default is the actual pixel ratio of
/// the device. Set 1 to use as initial-scale 1 for the image
/// </summary>
double? PixelRatio { get; set; }

/// <summary>
/// A string indicating the image format. The default type is image/png; that type is also used if the given type isn't supported.
/// </summary>
string? Type { get; set; }
}
2 changes: 0 additions & 2 deletions src/BootstrapBlazor/wwwroot/lib/html2image/html-to-image.js

This file was deleted.

11 changes: 0 additions & 11 deletions src/BootstrapBlazor/wwwroot/modules/html2image.js

This file was deleted.

22 changes: 22 additions & 0 deletions test/UnitTest/Services/Html2ImageServiceTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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([email protected]) Website: https://www.blazor.zone

namespace UnitTest.Services;

public class Html2ImageServiceTest
{
[Fact]
public async Task Html2Image_Error()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddBootstrapBlazor();

var provider = serviceCollection.BuildServiceProvider();
var html2ImageService = provider.GetRequiredService<IHtml2Image>();

await Assert.ThrowsAsync<NotImplementedException>(() => html2ImageService.GetDataAsync(".test", null));
await Assert.ThrowsAsync<NotImplementedException>(() => html2ImageService.GetStreamAsync(".test", null));
}
}