دریافت و نمایش فایلهای PDF در برنامههای Blazor WASM
نویسنده: وحید نصیری
تاریخ: ۱۴۰۰/۰۲/۱۵ ۱۱:۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
using Microsoft.AspNetCore.Mvc;
namespace BlazorWasmShowBinaryFiles.Server.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class ReportsController : ControllerBase
{
[HttpGet("[action]")]
public IActionResult GetPdfReport()
{
//TODO: create the `sample.pdf` report file on the server
return File(virtualPath: "~/app_data/sample.pdf",
contentType: "application/pdf",
fileDownloadName: "sample.pdf");
}
}
} window.JsBinaryFilesUtils = {
createBlobUrl: function (byteArray, contentType) {
// The byte array in .NET is encoded to base64 string when it passes to JavaScript.
const numArray = atob(byteArray)
.split("")
.map((c) => c.charCodeAt(0));
const uint8Array = new Uint8Array(numArray);
const blob = new Blob([uint8Array], { type: contentType });
return URL.createObjectURL(blob);
},
downloadFromUrl: function (fileName, url) {
const anchor = document.createElement("a");
anchor.style.display = "none";
anchor.href = url;
anchor.download = fileName;
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
},
downloadBlazorByteArray: function (fileName, byteArray, contentType) {
const blobUrl = this.createBlobUrl(byteArray, contentType);
this.downloadFromUrl(fileName, blobUrl);
URL.revokeObjectURL(blobUrl);
},
printFromUrl: function (url) {
const iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = url;
document.body.appendChild(iframe);
if (iframe.contentWindow) {
iframe.contentWindow.print();
}
},
printBlazorByteArray: function (byteArray, contentType) {
const blobUrl = this.createBlobUrl(byteArray, contentType);
this.printFromUrl(blobUrl);
URL.revokeObjectURL(blobUrl);
},
showUrlInNewTab: function (url) {
window.open(url);
},
showBlazorByteArrayInNewTab: function (byteArray, contentType) {
const blobUrl = this.createBlobUrl(byteArray, contentType);
this.showUrlInNewTab(blobUrl);
URL.revokeObjectURL(blobUrl);
},
}; using System.Threading.Tasks;
using Microsoft.JSInterop;
namespace BlazorWasmShowBinaryFiles.Client.Utils
{
public static class JsBinaryFilesUtils
{
public static ValueTask<string> CreateBlobUrlAsync(
this IJSRuntime JSRuntime,
byte[] byteArray, string contentType)
{
return JSRuntime.InvokeAsync<string>("JsBinaryFilesUtils.createBlobUrl", byteArray, contentType);
}
public static ValueTask DownloadFromUrlAsync(this IJSRuntime JSRuntime, string fileName, string url)
{
return JSRuntime.InvokeVoidAsync("JsBinaryFilesUtils.downloadFromUrl", fileName, url);
}
public static ValueTask DownloadBlazorByteArrayAsync(
this IJSRuntime JSRuntime,
string fileName, byte[] byteArray, string contentType)
{
return JSRuntime.InvokeVoidAsync("JsBinaryFilesUtils.downloadBlazorByteArray",
fileName, byteArray, contentType);
}
public static ValueTask PrintFromUrlAsync(this IJSRuntime JSRuntime, string url)
{
return JSRuntime.InvokeVoidAsync("JsBinaryFilesUtils.printFromUrl", url);
}
public static ValueTask PrintBlazorByteArrayAsync(
this IJSRuntime JSRuntime,
byte[] byteArray, string contentType)
{
return JSRuntime.InvokeVoidAsync("JsBinaryFilesUtils.printBlazorByteArray", byteArray, contentType);
}
public static ValueTask ShowUrlInNewTabAsync(this IJSRuntime JSRuntime, string url)
{
return JSRuntime.InvokeVoidAsync("JsBinaryFilesUtils.showUrlInNewTab", url);
}
public static ValueTask ShowBlazorByteArrayInNewTabAsync(
this IJSRuntime JSRuntime,
byte[] byteArray, string contentType)
{
return JSRuntime.InvokeVoidAsync("JsBinaryFilesUtils.showBlazorByteArrayInNewTab", byteArray, contentType);
}
}
} img-src 'self' data: blob: default-src 'self' blob: object-src 'self' blob:
@page "/"
@using BlazorWasmShowBinaryFiles.Client.Utils
@inject IJSRuntime JSRuntime
@inject HttpClient HttpClient
<h1>Display PDF Files</h1>
<button class="btn btn-info" @onclick="handlePrintPdf">Print PDF</button>
<button class="btn btn-primary ml-2" @onclick="handleShowPdf">Show PDF</button>
<button class="btn btn-success ml-2" @onclick="handleDownloadPdf">Download PDF</button>
@if(!string.IsNullOrWhiteSpace(PdfBlobUrl))
{
<section class="card mb-5 mt-3">
<div class="card-header">
<h4>using iframe</h4>
</div>
<div class="card-body">
<iframe title="PDF Report" width="100%" height="600" src="@PdfBlobUrl" type="@PdfContentType"></iframe>
</div>
</section>
<section class="card mb-5">
<div class="card-header">
<h4>using object</h4>
</div>
<div class="card-body">
<object data="@PdfBlobUrl" aria-label="PDF Report" type="@PdfContentType" width="100%" height="100%"></object>
</div>
</section>
<section class="card mb-5">
<div class="card-header">
<h4>using embed</h4>
</div>
<div class="card-body">
<embed aria-label="PDF Report" src="@PdfBlobUrl" type="@PdfContentType" width="100%" height="100%">
</div>
</section>
}
@code
{
private const string ReportUrl = "/api/Reports/GetPdfReport";
private const string PdfContentType = "application/pdf";
private string PdfBlobUrl;
private async Task handlePrintPdf()
{
// Note: Using the `HttpClient` is useful for accessing the protected API's by JWT's (non cookie-based authorization).
// Otherwise just use the `PrintFromUrlAsync` method.
var byteArray = await HttpClient.GetByteArrayAsync(ReportUrl);
await JSRuntime.PrintBlazorByteArrayAsync(byteArray, PdfContentType);
}
private async Task handleDownloadPdf()
{
// Note: Using the `HttpClient` is useful for accessing the protected API's by JWT's (non cookie-based authorization).
// Otherwise just use the `DownloadFromUrlAsync` method.
var byteArray = await HttpClient.GetByteArrayAsync(ReportUrl);
await JSRuntime.DownloadBlazorByteArrayAsync("report.pdf", byteArray, PdfContentType);
}
private async Task handleShowPdf()
{
// Note: Using the `HttpClient` is useful for accessing the protected API's by JWT's (non cookie-based authorization).
// Otherwise just use the `ReportUrl` as the `src` of the `iframe` directly.
var byteArray = await HttpClient.GetByteArrayAsync(ReportUrl);
PdfBlobUrl = await JSRuntime.CreateBlobUrlAsync(byteArray, PdfContentType);
}
// Tips:
// 1- How do I enable/disable the built-in pdf viewer of FireFox
// https://support.mozilla.org/en-US/kb/disable-built-pdf-viewer-and-use-another-viewer
// 2- How to configure browsers to use the Adobe PDF plug-in to open PDF files
// https://helpx.adobe.com/acrobat/kb/pdf-browser-plugin-configuration.html
// https://helpx.adobe.com/acrobat/using/display-pdf-in-browser.html
// 3- Microsoft Edge is gaining new PDF reader features within the Windows 10 Fall Creator’s Update (version 1709).
} Microsoft.JSInterop.JSException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded. Error: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded. at Object.createBlobUrl
window.JsBinaryFilesUtils = {
createBlobUrl: function (byteArray, contentType) {
// The byte array in .NET is encoded to base64 string when it passes to JavaScript.
const numArray = atob(byteArray)
.split("")
.map((c) => c.charCodeAt(0));
const uint8Array = new Uint8Array(numArray);
const blob = new Blob([uint8Array], { type: contentType });
return URL.createObjectURL(blob);
}, window.JsBinaryFilesUtils = {
createBlobUrl: function (byteArray, contentType) {
const blob = new Blob([byteArray], { type: contentType });
return URL.createObjectURL(blob);
}, report.DataSources.Add(new ReportDataSource("Header", "از نوع لیست باشد"));