diff --git a/blazorbootstrap/Components/PdfViewer/PdfViewer.razor b/blazorbootstrap/Components/PdfViewer/PdfViewer.razor
index 6829314c7..e4f116bb2 100644
--- a/blazorbootstrap/Components/PdfViewer/PdfViewer.razor
+++ b/blazorbootstrap/Components/PdfViewer/PdfViewer.razor
@@ -35,7 +35,8 @@
Switch Orientation
Go to First Page
Go to Last Page
- Reset Zoom
+ Reset Zoom
+ Download
diff --git a/blazorbootstrap/Components/PdfViewer/PdfViewer.razor.cs b/blazorbootstrap/Components/PdfViewer/PdfViewer.razor.cs
index 5a0056530..e4bb9e010 100644
--- a/blazorbootstrap/Components/PdfViewer/PdfViewer.razor.cs
+++ b/blazorbootstrap/Components/PdfViewer/PdfViewer.razor.cs
@@ -128,6 +128,8 @@ private async Task PageNumberChangedAsync(int value)
private async Task PrintAsync() => await PdfViewerJsInterop.PrintAsync(objRef!, Id!, Url!);
+ private async Task DownloadAsync() => await PdfViewerJsInterop.DownloadAsync(objRef!, Id!, Url!);
+
private async Task ResetZoomAsync()
{
zoomLevel = defaultZoomLevel;
diff --git a/blazorbootstrap/Components/PdfViewer/PdfViewerJsInterop.cs b/blazorbootstrap/Components/PdfViewer/PdfViewerJsInterop.cs
index 93bfc7f48..59ed76b68 100644
--- a/blazorbootstrap/Components/PdfViewer/PdfViewerJsInterop.cs
+++ b/blazorbootstrap/Components/PdfViewer/PdfViewerJsInterop.cs
@@ -82,5 +82,11 @@ public async Task ZoomInOutAsync(object objRef, string elementId, double scale)
await module.InvokeVoidAsync("zoomInOut", objRef, elementId, scale);
}
+ public async Task DownloadAsync(object objRef, string elementId, string url)
+ {
+ var module = await moduleTask.Value;
+ await module.InvokeVoidAsync("downloadDocument", objRef, elementId, "document.pdf");
+ }
+
#endregion
}
diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.pdf.js b/blazorbootstrap/wwwroot/blazor.bootstrap.pdf.js
index 67c3e3b02..4ada24ba2 100644
--- a/blazorbootstrap/wwwroot/blazor.bootstrap.pdf.js
+++ b/blazorbootstrap/wwwroot/blazor.bootstrap.pdf.js
@@ -46,6 +46,7 @@ class Pdf {
this.pageNumPending = null;
this.scale = 1;
this.rotation = 0;
+ this.url = '';
pdfInstances[this.id] = this;
}
@@ -198,7 +199,7 @@ export function initialize(dotNetHelper, elementId, scale, rotation, url) {
const pdf = new Pdf(elementId);
pdf.scale = scale;
pdf.rotation = rotation;
-
+ pdf.url = url;
pdfJS.getDocument(url).promise.then(function (doc) {
pdf.pdfDoc = doc;
pdf.pagesCount = doc.numPages;
@@ -265,3 +266,42 @@ function setPdfViewerMetaData(dotNetHelper, pdf) {
dotNetHelper.invokeMethodAsync('SetPdfViewerMetaData', { pagesCount: pdf.pagesCount, pageNumber: pdf.pageNum });
}
+
+export function downloadDocument(dotNetHelper, elementId, filename) {
+ const pdf = Pdf.getPdf(elementId);
+ if (pdf.url) {
+ if (pdf.url.indexOf('data:') === 0) {
+ const split = pdf.url.split(',');
+ const base64Data = split.length > 1 ? split[1] : '';
+ try {
+ saveAsFile(filename, base64Data)
+ } catch (e) {
+ console.error('Failed to decode base64 PDF:', e);
+ }
+ }
+ else {
+ saveAsFileFromUrl(pdf.url)
+ }
+ }
+ else {
+ console.error('Pdf Url empty');
+ }
+}
+
+function saveAsFile(filename, byteBase64) {
+ var link = document.createElement('a');
+ link.download = filename;
+ link.href = "data:application/octet-stream;base64," + byteBase64;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+}
+
+function saveAsFileFromUrl(url) {
+ var link = document.createElement('a');
+ link.href = url;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+}
+