Skip to content

Commit dffb489

Browse files
authored
feat(PdfReader): add OnDownloadAsync function (#727)
* refactor: 移除 PdfReaderOptions 配置类 * feat: 增加 resetTwoPagesOneView 方法
1 parent cb616bd commit dffb489

4 files changed

Lines changed: 174 additions & 142 deletions

File tree

src/components/BootstrapBlazor.PdfReader/PdfReader.razor

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
@inherits BootstrapModuleComponentBase
44

55
<div @attributes="@AdditionalAttributes" id="@Id" class="@ClassString" style="@StyleString">
6-
@if (Options.ShowToolbar)
6+
@if (ShowToolbar)
77
{
88
<div class="bb-view-toolbar init">
99
<div class="bb-view-title">
@@ -23,12 +23,15 @@
2323
<div class="bb-view-icon bb-view-fit-rotate" @onclick="RotateRight"><i class="fa-solid fa-rotate-right"></i></div>
2424
</div>
2525
<div class="bb-view-controls">
26-
<div class="bb-view-icon bb-view-download"><i class="fa-solid fa-arrow-right-to-bracket fa-rotate-90"></i></div>
26+
@if (ShowDownload)
27+
{
28+
<div class="bb-view-icon bb-view-download" @onclick="OnDownload"><i class="fa-solid fa-arrow-right-to-bracket fa-rotate-90"></i></div>
29+
}
2730
<div class="bb-view-icon bb-view-print"><i class="fa-solid fa-print"></i></div>
2831
<Dropdown TValue="string" Color="Color.None" SkipValidate="true" ShowLabel="false"
2932
IsPopover="false" MenuAlignment="Alignment.Right" Icon="@MoreButtonIcon">
3033
<ItemsTemplate>
31-
@if (Options.ShowTwoPagesOnViewButton)
34+
@if (ShowTwoPagesOneViewButton)
3235
{
3336
<div class="dropdown-item dropdown-item-pages" @onclick="OnToggleTwoPagesOneView"><i class="@_twoPagesOneViewIcon"></i><span>Two pages on view</span></div>
3437
<Divider></Divider>
@@ -40,7 +43,7 @@
4043
</div>
4144
}
4245
<div class="bb-view-main">
43-
@if (Options.EnableThumbnails)
46+
@if (EnableThumbnails)
4447
{
4548
<div class="bb-view-thumbnails"></div>
4649
}

src/components/BootstrapBlazor.PdfReader/PdfReader.razor.cs

Lines changed: 148 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,115 @@ namespace BootstrapBlazor.Components;
1414
public partial class PdfReader
1515
{
1616
/// <summary>
17-
/// 获得/设置 <see cref="PdfReaderOptions"/> 配置项实例
17+
/// 获得/设置 是否显示工具栏 默认 true 显示
1818
/// </summary>
1919
[Parameter]
20-
[NotNull]
21-
public PdfReaderOptions? Options { get; set; }
20+
public bool ShowToolbar { get; set; } = true;
21+
22+
/// <summary>
23+
/// 获得/设置 是否显示下载按钮 默认 true 显示
24+
/// </summary>
25+
[Parameter]
26+
public bool ShowDownload { get; set; } = true;
27+
28+
/// <summary>
29+
/// 获得/设置 是否显示缩略图 默认 true 显示
30+
/// </summary>
31+
[Parameter]
32+
public bool EnableThumbnails { get; set; } = true;
33+
34+
/// <summary>
35+
/// 获得/设置 PDF 文档路径
36+
/// </summary>
37+
[Parameter]
38+
public string? Url { get; set; }
39+
40+
/// <summary>
41+
/// 获得/设置 PDF 组件高度 默认 600px
42+
/// </summary>
43+
[Parameter]
44+
public string? ViewHeight { get; set; }
45+
46+
/// <summary>
47+
/// 获得/设置 当前页码
48+
/// </summary>
49+
[Parameter]
50+
public uint CurrentPage { get; set; }
51+
52+
/// <summary>
53+
/// 获得/设置 当前缩放倍率 默认 null 使用 100%
54+
/// </summary>
55+
[Parameter]
56+
public string? CurrentScale { get; set; }
57+
58+
/// <summary>
59+
/// 获得/设置 是否适配当前页面宽度 默认 false
60+
/// </summary>
61+
[Parameter]
62+
public bool IsFitToPage { get; set; }
63+
64+
/// <summary>
65+
/// 获得/设置 是否显示双页单视图按钮 默认 true 显示
66+
/// </summary>
67+
[Parameter]
68+
public bool ShowTwoPagesOneViewButton { get; set; } = true;
69+
70+
/// <summary>
71+
/// 获得/设置 是否启用双页单视图模式 默认 false
72+
/// </summary>
73+
[Parameter]
74+
public bool EnableTwoPagesOneView { get; set; }
75+
76+
/// <summary>
77+
/// 页面初始化回调方法
78+
/// </summary>
79+
[Parameter]
80+
public Func<int, Task>? OnPagesInitAsync { get; set; }
81+
82+
/// <summary>
83+
/// 页面加载完毕回调方法
84+
/// </summary>
85+
[Parameter]
86+
public Func<int, Task>? OnPagesLoadedAsync { get; set; }
87+
88+
/// <summary>
89+
/// 页面初始化回调方法
90+
/// </summary>
91+
[Parameter]
92+
public Func<uint, Task>? OnPageChangedAsync { get; set; }
93+
94+
/// <summary>
95+
/// 设置双页单视图模式回调方法
96+
/// </summary>
97+
[Parameter]
98+
public Func<bool, Task>? OnTwoPagesOneViewAsync { get; set; }
2299

23100
/// <summary>
24101
/// 获得/设置 更多按钮图标 默认为 null 使用内置图标
25102
/// </summary>
26103
[Parameter]
27104
public string? MoreButtonIcon { get; set; }
28105

106+
/// <summary>
107+
/// 点击下载按钮回调方法 默认 null 使用组件内置下载功能
108+
/// </summary>
109+
[Parameter]
110+
public Func<Task>? OnDownloadAsync { get; set; }
111+
112+
[Inject, NotNull]
113+
private DownloadService? DownloadService { get; set; }
114+
29115
private string? ClassString => CssBuilder.Default("bb-pdf-reader")
30116
.AddClassFromAttributes(AdditionalAttributes)
31117
.Build();
32118

33119
private string? StyleString => CssBuilder.Default()
34-
.AddClass($"--bb-pdf-view-height: {Options.ViewHeight};", !string.IsNullOrEmpty(Options.ViewHeight))
120+
.AddClass($"--bb-pdf-view-height: {ViewHeight};", !string.IsNullOrEmpty(ViewHeight))
35121
.AddClassFromAttributes(AdditionalAttributes)
36122
.Build();
37123

38124
private string? ViewBodyString => CssBuilder.Default("bb-view-body")
39-
.AddClass("fit-page", Options.IsFitToPage)
125+
.AddClass("fit-page", IsFitToPage)
40126
.Build();
41127

42128
private string? _docTitle;
@@ -45,35 +131,36 @@ public partial class PdfReader
45131
private string? _url;
46132
private string? _currentScale;
47133
private bool _enableTwoPagesOneView;
134+
private bool _showTwoPagesOneViewButton;
48135
private string? _twoPagesOneViewIcon;
49136

50137
private readonly HashSet<string> AllowedScaleValues = ["page-actual", "page-width", "page-height", "page-fit", "auto"];
51138

52139
private string CurrentPageString
53140
{
54-
get => Options.CurrentPage.ToString(CultureInfo.InvariantCulture);
141+
get => CurrentPage.ToString(CultureInfo.InvariantCulture);
55142
set => SetCurrentPage(value);
56143
}
57144

58145
private void SetCurrentPage(string value)
59146
{
60147
if (uint.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var num))
61148
{
62-
Options.CurrentPage = num;
149+
CurrentPage = num;
63150
}
64151
}
65152

66153
private string CurrentScaleString
67154
{
68-
get => $"{Options.CurrentScale ?? "100"}%";
155+
get => $"{CurrentScale ?? "100"}%";
69156
set => SetCurrentScale(value);
70157
}
71158

72159
private void SetCurrentScale(string value)
73160
{
74161
if (string.IsNullOrEmpty(value))
75162
{
76-
Options.CurrentScale = "100";
163+
CurrentScale = "100";
77164
}
78165
else if (float.TryParse(value.TrimEnd("%"), out var v))
79166
{
@@ -84,14 +171,14 @@ private void SetCurrentScale(string value)
84171
_ => v
85172
};
86173

87-
Options.CurrentScale = v.ToString(CultureInfo.InvariantCulture);
174+
CurrentScale = v.ToString(CultureInfo.InvariantCulture);
88175
}
89176
}
90177

91178
private void OnToggleTwoPagesOneView()
92179
{
93180
_enableTwoPagesOneView = !_enableTwoPagesOneView;
94-
Options.EnableTwoPagesOnView = _enableTwoPagesOneView;
181+
EnableTwoPagesOneView = _enableTwoPagesOneView;
95182

96183
_twoPagesOneViewIcon = _enableTwoPagesOneView ? "fa-solid fa-fw fa-check" : "fa-solid fa-fw";
97184
}
@@ -103,16 +190,14 @@ protected override void OnParametersSet()
103190
{
104191
base.OnParametersSet();
105192

106-
Options ??= new PdfReaderOptions();
193+
MoreButtonIcon ??= "fa-solid fa-ellipsis-vertical";
194+
_twoPagesOneViewIcon ??= "fa-solid fa-fw";
107195

108-
if (Options.CurrentPage == 0)
196+
if (CurrentPage == 0)
109197
{
110-
Options.CurrentPage = 1;
198+
CurrentPage = 1;
111199
}
112-
_docTitle = Path.GetFileName(Options.Url);
113-
114-
MoreButtonIcon ??= "fa-solid fa-ellipsis-vertical";
115-
_twoPagesOneViewIcon ??= "fa-solid fa-fw";
200+
_docTitle = Path.GetFileName(Url);
116201
}
117202

118203
/// <summary>
@@ -126,37 +211,43 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
126211

127212
if (firstRender)
128213
{
129-
_isFitToPage = Options.IsFitToPage;
130-
_currentPage = Options.CurrentPage;
131-
_url = Options.Url;
132-
_currentScale = Options.CurrentScale;
133-
_enableTwoPagesOneView = Options.EnableTwoPagesOnView;
214+
_isFitToPage = IsFitToPage;
215+
_currentPage = CurrentPage;
216+
_url = Url;
217+
_currentScale = CurrentScale;
218+
_enableTwoPagesOneView = EnableTwoPagesOneView;
219+
_showTwoPagesOneViewButton = ShowTwoPagesOneViewButton;
134220
}
135221

136-
if (_url != Options.Url)
222+
if (_url != Url)
137223
{
138-
_url = Options.Url;
224+
_url = Url;
139225
await InvokeInitAsync();
140226
}
141227

142-
if (_isFitToPage != Options.IsFitToPage)
228+
if (_isFitToPage != IsFitToPage)
143229
{
144-
_isFitToPage = Options.IsFitToPage;
230+
_isFitToPage = IsFitToPage;
145231
await TriggerFit(_isFitToPage ? "fitToPage" : "fitToWidth");
146232
}
147-
if (_currentPage != Options.CurrentPage)
233+
if (_currentPage != CurrentPage)
148234
{
149-
_currentPage = Options.CurrentPage;
235+
_currentPage = CurrentPage;
150236
await NavigateToPageAsync(_currentPage);
151237
}
152-
if (_currentScale != Options.CurrentScale)
238+
if (_currentScale != CurrentScale)
153239
{
154-
_currentScale = Options.CurrentScale;
240+
_currentScale = CurrentScale;
155241
await InvokeVoidAsync("scale", Id, _currentScale);
156242
}
157-
if (_enableTwoPagesOneView != Options.EnableTwoPagesOnView)
243+
if (_enableTwoPagesOneView != EnableTwoPagesOneView)
158244
{
159-
_currentScale = Options.CurrentScale;
245+
_enableTwoPagesOneView = EnableTwoPagesOneView;
246+
await InvokeVoidAsync("setPages", Id, _enableTwoPagesOneView);
247+
}
248+
if (_showTwoPagesOneViewButton != ShowTwoPagesOneViewButton)
249+
{
250+
_showTwoPagesOneViewButton = ShowTwoPagesOneViewButton;
160251
await InvokeVoidAsync("setPages", Id, _enableTwoPagesOneView);
161252
}
162253
}
@@ -167,13 +258,13 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
167258
/// <returns></returns>
168259
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, new
169260
{
170-
Options.Url,
171-
Options.IsFitToPage,
172-
Options.EnableThumbnails,
173-
TriggerPagesInit = Options.OnPagesInitAsync != null,
174-
TriggerPagesLoaded = Options.OnPagesLoadedAsync != null,
175-
TriggerPageChanged = Options.OnPageChangedAsync != null,
176-
TriggerTowPagesOnViewChanged = Options.OnTwoPagesOneViewAsync != null
261+
Url,
262+
IsFitToPage,
263+
EnableThumbnails,
264+
TriggerPagesInit = OnPagesInitAsync != null,
265+
TriggerPagesLoaded = OnPagesLoadedAsync != null,
266+
TriggerPageChanged = OnPageChangedAsync != null,
267+
TriggerTowPagesOnViewChanged = OnTwoPagesOneViewAsync != null
177268
});
178269

179270
/// <summary>
@@ -186,12 +277,12 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
186277
/// <summary>
187278
/// 适应页面宽度
188279
/// </summary>
189-
public void FitToPage() => Options.IsFitToPage = true;
280+
public void FitToPage() => IsFitToPage = true;
190281

191282
/// <summary>
192283
/// 适应文档宽度
193284
/// </summary>
194-
public void FitToWidth() => Options.IsFitToPage = false;
285+
public void FitToWidth() => IsFitToPage = false;
195286

196287
/// <summary>
197288
/// 旋转页面方法
@@ -211,6 +302,14 @@ public async Task RotateRight()
211302
await InvokeVoidAsync("rotate", Id, 90);
212303
}
213304

305+
private async Task OnDownload()
306+
{
307+
if (OnDownloadAsync != null)
308+
{
309+
await OnDownloadAsync();
310+
}
311+
}
312+
214313
private Task TriggerFit(string methodName) => InvokeVoidAsync(methodName, Id);
215314

216315
/// <summary>
@@ -220,9 +319,9 @@ public async Task RotateRight()
220319
[JSInvokable]
221320
public async Task PagesInit(int pagesCount)
222321
{
223-
if (Options.OnPagesInitAsync != null)
322+
if (OnPagesInitAsync != null)
224323
{
225-
await Options.OnPagesInitAsync(pagesCount);
324+
await OnPagesInitAsync(pagesCount);
226325
}
227326
}
228327

@@ -233,9 +332,9 @@ public async Task PagesInit(int pagesCount)
233332
[JSInvokable]
234333
public async Task PagesLoaded(int pagesCount)
235334
{
236-
if (Options.OnPagesLoadedAsync != null)
335+
if (OnPagesLoadedAsync != null)
237336
{
238-
await Options.OnPagesLoadedAsync(pagesCount);
337+
await OnPagesLoadedAsync(pagesCount);
239338
}
240339
}
241340

@@ -247,11 +346,11 @@ public async Task PagesLoaded(int pagesCount)
247346
public async Task PageChanged(uint pageIndex)
248347
{
249348
_currentPage = pageIndex;
250-
Options.CurrentPage = pageIndex;
349+
CurrentPage = pageIndex;
251350

252-
if (Options.OnPageChangedAsync != null)
351+
if (OnPageChangedAsync != null)
253352
{
254-
await Options.OnPageChangedAsync(pageIndex);
353+
await OnPageChangedAsync(pageIndex);
255354
}
256355
}
257356
}

0 commit comments

Comments
 (0)