@page "/reportviewer/" @using System.Drawing @using DevExpress.Drawing @using DevExpress.Utils @using DevExpress.XtraPrinting @using DevExpress.XtraPrinting.Drawing @using DevExpress.XtraReports.UI; @using EnvelopeGenerator.ReceiverUI.Services; @inject IJSRuntime JSRuntime @inject InMemoryReportStorageWebExtension ReportStorage
Unterschrift

Bitte fuegen Sie vor dem PDF-Export Ihre Unterschrift in das Feld unten ein.

@if(!string.IsNullOrWhiteSpace(SignatureValidationMessage)) {
@SignatureValidationMessage
}
@if(Report is not null) { } @code { DxReportViewer reportViewer; XtraReport? Report; bool SignatureApplied; string? SignatureValidationMessage; protected override async Task OnInitializedAsync() { Report = ReportStorage.TryGetReport("LargeDatasetReport", out var savedReport) ? savedReport : PredefinedReports.ReportsFactory.GetReport("LargeDatasetReport"); await Task.CompletedTask; } protected override async Task OnAfterRenderAsync(bool firstRender) { if(firstRender) await JSRuntime.InvokeVoidAsync("receiverSignature.initialize", "receiver-signature-pad"); } async Task ClearSignatureAsync() { await JSRuntime.InvokeVoidAsync("receiverSignature.clear", "receiver-signature-pad"); SignatureApplied = false; SignatureValidationMessage = null; Report = ReportStorage.TryGetReport("LargeDatasetReport", out var savedReport) ? savedReport : PredefinedReports.ReportsFactory.GetReport("LargeDatasetReport"); if(reportViewer is not null) await reportViewer.OpenReportAsync(Report); } async Task ApplySignatureAsync() { var signatureDataUrl = await JSRuntime.InvokeAsync("receiverSignature.getDataUrl", "receiver-signature-pad"); if(string.IsNullOrWhiteSpace(signatureDataUrl)) { SignatureApplied = false; SignatureValidationMessage = "Die Unterschrift ist fuer den PDF-Export erforderlich."; return; } SignatureValidationMessage = null; ApplySignatureToReport(signatureDataUrl); SignatureApplied = true; if(reportViewer is not null) await reportViewer.OpenReportAsync(Report); } async Task ExportSignedPdfAsync() { if(!SignatureApplied || Report is null) { SignatureValidationMessage = "Bitte fuegen Sie die Unterschrift zuerst zum Bericht hinzu."; return; } await reportViewer.ExportToAsync(ExportFormat.Pdf); } void ApplySignatureToReport(string signatureDataUrl) { Report ??= ReportStorage.TryGetReport("LargeDatasetReport", out var savedReport) ? savedReport : PredefinedReports.ReportsFactory.GetReport("LargeDatasetReport"); AddSignature(Report, signatureDataUrl); } static void AddSignature(XtraReport report, string signatureDataUrl) { var imageBytes = Convert.FromBase64String(signatureDataUrl[(signatureDataUrl.IndexOf(',') + 1)..]); using var imageStream = new MemoryStream(imageBytes); var imageSource = new ImageSource(DXImage.FromStream(imageStream)); var bottomMargin = report.Bands.OfType().FirstOrDefault(); if(bottomMargin is null) { bottomMargin = new BottomMarginBand(); report.Bands.Add(bottomMargin); } bottomMargin.HeightF = Math.Max(bottomMargin.HeightF, 120F); RemoveExistingSignature(bottomMargin); var signatureLabel = new XRLabel { Name = "receiverSignatureLabel", Text = $"Empfaengerunterschrift - {DateTime.Now:g}", BoundsF = new RectangleF(390F, 6F, 230F, 18F), Font = new DXFont("Open Sans", 8F, DXFontStyle.Bold), ForeColor = System.Drawing.Color.FromArgb(73, 80, 87), TextAlignment = TextAlignment.MiddleLeft }; var signature = new XRPictureBox { Name = "receiverSignatureImage", ImageSource = imageSource, BoundsF = new RectangleF(390F, 28F, 230F, 70F), Sizing = ImageSizeMode.ZoomImage, Borders = BorderSide.Bottom, BorderColor = System.Drawing.Color.FromArgb(73, 80, 87) }; bottomMargin.Controls.AddRange(new XRControl[] { signatureLabel, signature }); } static void RemoveExistingSignature(BottomMarginBand bottomMargin) { var controls = bottomMargin.Controls .Cast() .Where(control => control.Name is "receiverSignatureLabel" or "receiverSignatureImage") .ToArray(); foreach(var control in controls) bottomMargin.Controls.Remove(control); } }