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); +} +