First, report PDF needs to be created. I call a method to create a PDF as BASE64String and then use JavaScript to show it.
protected async System.Threading.Tasks.Task ButtonViewJsClick(MouseEventArgs args)
{
htmlString = DownloadReportAsPDFBase64String("Belegnr="+Belegnummer.ToString());
await JSRuntime.InvokeVoidAsync("openPdfInNewTab", htmlString);
}
The Method DownloadReportAsPDFBase64String("Belegnr="+Belegnummer.ToString()); looks like:
private String DownloadReportAsPDFBase64String(string filter)
{
// Getting SSRS URL from system settings
var ReportingServicesURL = EEvolution.GetSystem1S(new Query() { Filter = $@"i => i.para == @0", FilterParameters = new object[] { "eEvolutionProfessional_ReportingServicesURL" } });
// Getting possible subfolder on report server from system settings
var ReportingServicesFolder = EEvolution.GetSystem1S(new Query() { Filter = $@"i => i.para == @0", FilterParameters = new object[] { "eEvolutionProfessional_ReportingServicesFolder" } });
string BelegtemplateLocal = Belegtemplate;
// Adds subfolder to template path
if (!String.IsNullOrEmpty(ReportingServicesFolder.Result.FirstOrDefault().WERT))
{
Belegtemplate = ReportingServicesFolder.Result.FirstOrDefault().WERT + "/" + Belegtemplate;
}
string reportServerUrl = ReportingServicesURL.Result.FirstOrDefault().WERT;
string reportPath = Belegtemplate;
// Generates filename for PDF
string outputPath = GetFilename(Belegnummer.ToString(), Belegtemplate);
// Call Downloadservice
var stream = reportDownloaderService.DownloadReportAsStream(reportServerUrl, reportPath, filter).Result;
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms);
// Return BASE64 String from stream
return Convert.ToBase64String(ms.ToArray());
}
The method DownloadReportAsStream(reportServerUrl, reportPath, filter) looks like this:
public Task<Stream> DownloadReportAsStream(string reportServerUrl, string reportPath, string filter)
{
httpClient = CreateHttpClient();
// Delimiter einfügen, wenn noch nicht im Filterstring enthalten
if (!filter.StartsWith('&'))
{
filter = "&" + filter;
}
// Erstelle die URL zum Herunterladen des Berichts als PDF
string downloadUrl = $"{reportServerUrl}/Pages/ReportViewer.aspx?%2f{reportPath}&rs:Command=Render&rs:Embed=true&rc:Parameters=false&rs:ClearSession=true{filter}&rs:Format=PDF";
// Sende die Anforderung an den Berichtsserver und erhalte den Bericht als Stream zurück
using (var response = httpClient.GetAsync(downloadUrl))
{
response.Result.EnsureSuccessStatusCode();
// Lese den Berichtsstream und speichere ihn im angegebenen Ausgabepfad
var reportStream = response.Result.Content.ReadAsStreamAsync();
return reportStream;
}
}
Here is the code for CreateHttpClient():
private HttpClient CreateHttpClient()
{
var httpClientHandler = new HttpClientHandler();
httpClientHandler.AllowAutoRedirect = true;
httpClientHandler.UseDefaultCredentials = true;
if (httpClientHandler.SupportsAutomaticDecompression)
{
httpClientHandler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
}
OnHttpClientHandlerCreate(ref httpClientHandler);
return new HttpClient(httpClientHandler);
}
And OnHttpClientHandlerCreate(ref httpClientHandler), where SSRS credentials are read from system settings:
protected void OnHttpClientHandlerCreate(ref HttpClientHandler handler)
{
var User = context.System1s.Where(s => s.para == "eEvolutionProfessional_ReportingServicesUserName").Select(s => s.WERT).First();
var Password = new Services.CryptoService(Services.EMailReceiveService.SecretString).Decrypt(context.System1s.Where(s => s.para == "eEvolutionProfessional_ReportingServicesPassword").Select(s => s.WERT).First());
var Domain = context.System1s.Where(s => s.para == "eEvolutionProfessional_ReportingServicesUserDomain").Select(s => s.WERT).First();
if (!string.IsNullOrEmpty(User) && !string.IsNullOrEmpty(Password) && !string.IsNullOrEmpty(Domain))
{
handler.Credentials = new NetworkCredential(User, Password, Domain);
}
}
Coming back to the beginning:
protected async System.Threading.Tasks.Task ButtonViewJsClick(MouseEventArgs args)
{
htmlString = DownloadReportAsPDFBase64String("Belegnr="+Belegnummer.ToString());
await JSRuntime.InvokeVoidAsync("openPdfInNewTab", htmlString);
}
The missing bit is JavaScript Code in _Host.cshtml:
This:
<head>
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.9.359/pdf.min.js"></script>
...
</head>
And that, also in _Host.cshtml:
<body>
...
<script>
window.openPdfInNewTab = function (base64String) {
var byteArray = base64ToByteArray(base64String);
var blob = new Blob([byteArray], { type: 'application/pdf' });
var blobUrl = URL.createObjectURL(blob);
var newTab = window.open(blobUrl, '_blank');
window.onload = function () {
newTab.focus();
};
};
function base64ToByteArray(base64String) {
var binaryString = window.atob(base64String);
var byteArray = new Uint8Array(binaryString.length);
for (var i = 0; i < binaryString.length; i++) {
byteArray[i] = binaryString.charCodeAt(i);
}
return byteArray;
}
</script>
...
</body>
That´s it