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
9 changes: 5 additions & 4 deletions blazorbootstrap/Components/PdfViewer/PdfViewer.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ public void SetPdfViewerMetaData(PdfViewerModel pdfViewerModel)
OnPageChanged.InvokeAsync(new PdfViewerEventArgs(pageNumber, pagesCount));
}

private async Task DownloadPdf()
{
await PdfViewerJsInterop!.DownloadPdfAsync(objRef!, Id!, Url!);
}

private async Task FirstPageAsync() => await PdfViewerJsInterop!.FirstPageAsync(objRef!, Id!);

private int GetZoomPercentage(int zoomLevel) =>
Expand Down Expand Up @@ -225,10 +230,6 @@ private async Task ZoomOutAsync()
await PdfViewerJsInterop!.ZoomInOutAsync(objRef!, Id!, scale);
}

private async Task DownloadPdf()
{
await PdfViewerJsInterop!.DownloadPdfAsync(Url);
}
#endregion

#region Properties, Indexers
Expand Down
16 changes: 9 additions & 7 deletions blazorbootstrap/Components/PdfViewer/PdfViewerJsInterop.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

namespace BlazorBootstrap;
namespace BlazorBootstrap;

public class PdfViewerJsInterop : JsInteropBase
{
Expand All @@ -14,6 +13,14 @@ public PdfViewerJsInterop(IJSRuntime jsRuntime)

#region Methods

public async Task DownloadPdfAsync(object objRef, string elementId, string url)
{
if (string.IsNullOrWhiteSpace(url))
throw new ArgumentException("URL cannot be null or empty.", nameof(url));

await SafeInvokeVoidAsync("downloadPdf", objRef, elementId, url);
}

public async Task FirstPageAsync(object objRef, string elementId)
{
await SafeInvokeVoidAsync("firstPage", objRef, elementId);
Expand Down Expand Up @@ -58,10 +65,5 @@ public async Task ZoomInOutAsync(object objRef, string elementId, double scale)
{
await SafeInvokeVoidAsync("zoomInOut", objRef, elementId, scale);
}

public async Task DownloadPdfAsync(string fileUrl)
{
await SafeInvokeVoidAsync("downloadPdf", fileUrl);
}
#endregion
}
62 changes: 54 additions & 8 deletions blazorbootstrap/wwwroot/blazor.bootstrap.pdf.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,24 @@ class Pdf {
}
}

export function downloadPdf(dotNetHelper, elementId, url) {
if (url) {
if (url.indexOf('data:') === 0) {
const split = url.split(',');
const base64Data = split.length > 1 ? split[1] : '';
try {
saveAsFileFromBase64Data(base64Data);
} catch (e) {
console.error('Failed to trigger PDF download:', e);
}
} else {
saveAsFileFromUrl(url);
}
} else {
console.error('Pdf Url empty');
}
}

export function firstPage(dotNetHelper, elementId) {
const pdf = getPdf(elementId);

Expand All @@ -65,6 +83,11 @@ export function firstPage(dotNetHelper, elementId) {
setPdfViewerMetaData(dotNetHelper, pdf);
}

function getUUIDPDFName(prefix = 'document') {
const uuid = self.crypto.randomUUID(); // Built-in browser API
return `${prefix}-${uuid}.pdf`;
}

export function gotoPage(dotNetHelper, elementId, gotoPageNum) {
const pdf = getPdf(elementId);

Expand Down Expand Up @@ -170,6 +193,37 @@ export function rotate(dotNetHelper, elementId, rotation) {
queueRenderPage(pdf, pdf.pageNum);
}

function saveAsFileFromBase64Data(base64Data) {
const link = document.createElement('a');
link.download = getUUIDPDFName();
link.href = "data:application/pdf;base64," + base64Data;
link.style.display = 'none'; // Avoid potential layout/scroll quirks
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}

function saveAsFileFromUrl(url) {
// Validate the URL to ensure it uses an allowed scheme
const allowedSchemes = ['http:', 'https:', 'blob:'];
try {
const parsedUrl = new URL(url, window.location.origin);
if (!allowedSchemes.includes(parsedUrl.protocol)) {
console.error('Invalid URL scheme:', parsedUrl.protocol);
return;
}
} catch (e) {
console.error('Invalid URL:', e);
return;
}

var link = document.createElement('a');
link.href = url;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}

export function zoomInOut(dotNetHelper, elementId, scale) {
const pdf = getPdf(elementId);

Expand All @@ -182,14 +236,6 @@ export function zoomInOut(dotNetHelper, elementId, scale) {
queueRenderPage(pdf, pdf.pageNum);
}

export function downloadPdf(fileUrl) {
const link = document.createElement('a');
link.href = fileUrl;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}

// resize
// print
// download
Expand Down
Loading