@page "/reportviewer/" @using System.Drawing @using DevExpress.Drawing @using DevExpress.Utils @using DevExpress.XtraPrinting @using DevExpress.XtraPrinting.Drawing @using XtraReport = DevExpress.XtraReports.UI.XtraReport @using BottomMarginBand = DevExpress.XtraReports.UI.BottomMarginBand @using XRLabel = DevExpress.XtraReports.UI.XRLabel @using XRPictureBox = DevExpress.XtraReports.UI.XRPictureBox @using XRControl = DevExpress.XtraReports.UI.XRControl @using ImageSizeMode = DevExpress.XtraPrinting.ImageSizeMode @using EnvelopeGenerator.ReceiverUI.Services; @inject IJSRuntime JSRuntime @inject InMemoryReportStorageWebExtension ReportStorage
Unterschrift

@if(SignatureApplied) { Die Unterschrift wurde dem Bericht hinzugefuegt. Sie koennen die Unterschrift erneuern oder das signierte PDF exportieren. } else { Bitte fuegen Sie vor dem PDF-Export Ihre Unterschrift hinzu. }

@if(!string.IsNullOrWhiteSpace(SignatureValidationMessage)) {
@SignatureValidationMessage
}
@if(ActiveSignatureTab == SignatureTabDraw) {

Bitte unterschreiben Sie im folgenden Feld.

} else if(ActiveSignatureTab == SignatureTabText) {

Geben Sie Ihre Unterschrift als Text ein und waehlen Sie eine Schriftart.

} else {

Laden Sie ein Bild Ihrer Unterschrift hoch.

}

Bitte geben Sie die folgenden Angaben ein. Das Datum wird automatisch hinzugefuegt.

@if(!string.IsNullOrWhiteSpace(PopupValidationMessage)) {
@PopupValidationMessage
}
@if(Report is not null) { } @code { const string SignatureTabDraw = "draw"; const string SignatureTabText = "text"; const string SignatureTabImage = "image"; const string DrawCanvasId = "receiver-signature-pad"; const string TypedCanvasId = "receiver-typed-signature-pad"; const string ImageInputId = "receiver-signature-image-input"; const string ImageCanvasId = "receiver-image-signature-pad"; readonly (string Text, string Value)[] TypedSignatureFonts = { ("Brush Script", "'Brush Script MT', cursive"), ("Segoe Script", "'Segoe Script', cursive"), ("Lucida Handwriting", "'Lucida Handwriting', cursive"), ("Comic Sans", "'Comic Sans MS', cursive"), ("Cursive", "cursive") }; DxReportViewer reportViewer; XtraReport? Report; bool SignatureApplied; bool SignaturePopupVisible; string? SignatureValidationMessage; string? PopupValidationMessage; string ActiveSignatureTab = SignatureTabDraw; string TypedSignatureText = string.Empty; string TypedSignatureFont = "'Brush Script MT', cursive"; string SignerFullName = string.Empty; string SignerPosition = string.Empty; string SignaturePlace = string.Empty; int ViewerKey; protected override async Task OnInitializedAsync() { Report = CreateReportInstance(); await Task.CompletedTask; } async Task OpenSignaturePopupAsync() { ActiveSignatureTab = SignatureTabDraw; SignaturePopupVisible = true; SignatureValidationMessage = null; PopupValidationMessage = null; await InvokeAsync(StateHasChanged); await Task.Delay(50); await InitializeActiveSignatureTabAsync(); } async Task SetSignatureTabAsync(string tab) { ActiveSignatureTab = tab; PopupValidationMessage = null; await InvokeAsync(StateHasChanged); await Task.Delay(50); await InitializeActiveSignatureTabAsync(); } async Task InitializeActiveSignatureTabAsync() { if(ActiveSignatureTab == SignatureTabDraw) { await JSRuntime.InvokeVoidAsync("receiverSignature.initialize", DrawCanvasId); } else if(ActiveSignatureTab == SignatureTabText) { await JSRuntime.InvokeVoidAsync("receiverSignature.initializeTyped", TypedCanvasId); await RenderTypedSignatureAsync(); } else { await JSRuntime.InvokeVoidAsync("receiverSignature.initializeImage", ImageInputId, ImageCanvasId); } } async Task RenewSignatureAsync() { PopupValidationMessage = null; if(ActiveSignatureTab == SignatureTabDraw) { await JSRuntime.InvokeVoidAsync("receiverSignature.clear", DrawCanvasId); } else if(ActiveSignatureTab == SignatureTabText) { TypedSignatureText = string.Empty; await JSRuntime.InvokeVoidAsync("receiverSignature.clearTyped", TypedCanvasId); } else { await JSRuntime.InvokeVoidAsync("receiverSignature.clearImage", ImageInputId, ImageCanvasId); } } void CloseSignaturePopup() { PopupValidationMessage = null; SignaturePopupVisible = false; } async Task OnTypedSignatureChanged(Microsoft.AspNetCore.Components.ChangeEventArgs args) { TypedSignatureText = args.Value?.ToString() ?? string.Empty; await RenderTypedSignatureAsync(); } async Task OnTypedSignatureFontChanged(Microsoft.AspNetCore.Components.ChangeEventArgs args) { TypedSignatureFont = args.Value?.ToString() ?? TypedSignatureFont; await RenderTypedSignatureAsync(); } async Task RenderTypedSignatureAsync() { await JSRuntime.InvokeVoidAsync("receiverSignature.renderTypedSignature", TypedCanvasId, TypedSignatureText, TypedSignatureFont); } async Task ApplySignatureAsync() { if(string.IsNullOrWhiteSpace(SignerFullName)) { PopupValidationMessage = "Bitte geben Sie Vor- und Nachname ein."; return; } if(string.IsNullOrWhiteSpace(SignaturePlace)) { PopupValidationMessage = "Bitte geben Sie den Ort ein."; return; } var signatureDataUrl = await GetActiveSignatureDataUrlAsync(); if(string.IsNullOrWhiteSpace(signatureDataUrl)) { PopupValidationMessage = "Die Unterschrift ist fuer den PDF-Export erforderlich."; return; } PopupValidationMessage = null; SignatureValidationMessage = null; Report = CreateSignedReportInstance(signatureDataUrl, SignerFullName.Trim(), SignerPosition.Trim(), SignaturePlace.Trim()); SignatureApplied = true; SignaturePopupVisible = false; ViewerKey++; } async Task GetActiveSignatureDataUrlAsync() { if(ActiveSignatureTab == SignatureTabDraw) return await JSRuntime.InvokeAsync("receiverSignature.getDataUrl", DrawCanvasId); if(ActiveSignatureTab == SignatureTabText) { await RenderTypedSignatureAsync(); return await JSRuntime.InvokeAsync("receiverSignature.getTypedDataUrl", TypedCanvasId); } return await JSRuntime.InvokeAsync("receiverSignature.getImageDataUrl", ImageCanvasId); } async Task ExportSignedPdfAsync() { if(!SignatureApplied || Report is null) { SignatureValidationMessage = "Bitte fuegen Sie die Unterschrift zuerst zum Bericht hinzu."; return; } try { SignatureValidationMessage = null; await reportViewer.ExportToAsync(ExportFormat.Pdf); } catch(Exception) { SignatureValidationMessage = "Das signierte PDF konnte nicht exportiert werden. Bitte laden Sie die Seite neu und versuchen Sie es erneut."; } } XtraReport CreateReportInstance() { return ReportStorage.TryGetReport("LargeDatasetReport", out var savedReport) ? savedReport : PredefinedReports.ReportsFactory.GetReport("LargeDatasetReport"); } XtraReport CreateSignedReportInstance(string signatureDataUrl, string signerFullName, string signerPosition, string signaturePlace) { var report = CreateReportInstance(); AddSignature(report, signatureDataUrl, signerFullName, signerPosition, signaturePlace); return report; } static void AddSignature(XtraReport report, string signatureDataUrl, string signerFullName, string signerPosition, string signaturePlace) { 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, 140F); RemoveExistingSignature(bottomMargin); var signatureInformation = string.IsNullOrWhiteSpace(signerPosition) ? $"Empfaengerunterschrift\nName: {signerFullName}\nOrt: {signaturePlace}\nDatum: {DateTime.Now:g}" : $"Empfaengerunterschrift\nName: {signerFullName}\nPosition: {signerPosition}\nOrt: {signaturePlace}\nDatum: {DateTime.Now:g}"; var signatureLabel = new XRLabel { Name = "receiverSignatureLabel", Text = signatureInformation, BoundsF = new RectangleF(390F, 6F, 230F, 48F), 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, 58F, 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); } }