I found some bits of code from long ago but still can't figure it out.
Any up to date clear code You could give me ? I am using Angular/.NET core 5.0.
I am putting the report in the wwwroot and setting to copy always so the report seems to be there. The report has no parameters.
I get the error below
[HttpGet] //https://localhost:44374/reports/testreport public string TestReport() { string webRootPath = _webHostEnvironment.WebRootPath; var rptName = Path.Combine(webRootPath, "Reports\\AllForms.trdp"); var report = new Telerik.Reporting.Report { DocumentName = rptName }; var instanceReportSource = new InstanceReportSource { ReportDocument = report }; var reportProcessor = new ReportProcessor(); var result = reportProcessor.RenderReport("PDF", instanceReportSource, new Hashtable()); return "xxx"; }
The current data set presented in the report did not produce any significant content, so no pages were generated. If you need to see the whole report content, including blank pages, please contact the report author.
1 Answer, 1 is accepted
Hello Matt,
You may check out our Embedded Report Engine article. The first example demonstrates how one may export a report to PDF.
I would also recommend checking out the Exporting a report to PDF programmatically KB article.
Please note that you may also use the viewer's commands to export the report loaded in the report viewer so the same report that you wish to export should be the same report that has been loaded in the angular report viewer. For more information, please see the Angular - Commands article.
In the code snippet that you have provided, everything seems to be correct. The reason for this error being thrown is usually, that the report does not utilize a data source, the report has only blank pages(no data on them) or there is an issue with the data source component/s. The solution is setting SkipBlankPages of your Reports to False, which will prevent this behavior.
For more information, please see The Reports Are not Rendered or Generated Report Documents are Corrupted When the Data Set Comes Back Empty KB article.
Please let me know if you have any other questions.
Regards,
Dimitar
Progress Telerik
good stuff. Ill circle back around in a few weeks.. ON a related note I noticed I can't get one particular nuget package from the nuget feed so it is stopping me from building on the tfs server
Telerik.Reporting.Services.AspNetCore;
Is there a reason this is only on the telerik feed?
How do I get the file back to the browser ? I am close .
[HttpGet("TestReportCreation")] public IActionResult TestReportCreation() { string webRootPath = _webHostEnvironment.ContentRootPath; var reportProcessor = new Telerik.Reporting.Processing.ReportProcessor(); var deviceInfo = new System.Collections.Hashtable(); var uriReportSource = new Telerik.Reporting.UriReportSource(); uriReportSource.Uri = Path.Combine(webRootPath, "Reports\\ReportShowAllSubmitted.trdp"); var result = reportProcessor.RenderReport("PDF", uriReportSource, deviceInfo); if (!result.HasErrors) { string fileName = result.DocumentName + "." + result.Extension; string path = Path.GetTempPath(); string filePath = Path.Combine(path, fileName); using (FileStream fs = new FileStream(filePath, FileMode.Create)) { fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length); return File(fs, "application/octet-stream"); //this??? //return 500 error } } return null; }
For ASP.NET Core applications, you may return the result to the client as Base64 string so that no bytes are lost. Then, on the client, you can convert the result back to bytes where you may use them to download the PDF.
Please see the Exporting a report to PDF programmatically - For ASP.NET Core example for more details.
I have something similar that returns a downloadable file
PdfFormatProvider provider = new PdfFormatProvider(); return new FileContentResult(provider.Export(doc), "application/pdf") { FileDownloadName = scs[0].Serial1 + ".pdf" };
The variable 'doc' is a RadFixedDocument and the '.Export' function returns a 'byte[]' array
You should be able to use 'result.DocumentBytes' in that place
Think the below should work
if (!result.HasErrors)
{
return new FileContentResult(result.DocumentBytes, "application/pdf")
{
FileDownloadName = "Filename.pdf"
};
}
@Dimitar
I know the above worked when generating a byte[] array with PdfFormatPRovider from a RadFixedDocument so the updated code mentioned above with the bytes generated from the report processor should also work.
Personally, I think it's a better way to do it rather than converting with the base64 in both server and client. Probably the example could be updated then
Well.. it returns something
I am not doing anything on the angular side except a get request...
I am expecting the browser to show me the pdf SAVE AS dialouge but not happening...
I really don't understand this area so I feel like I am coding blindy..
Yes would be nice to have an angular project that shows the various ways to save reports... send reports... use parameters... All the sort of things you might do with a report outside of just using the viewer
otherwise my team is just going to use the telerik grid with an export button and thats not real reporting
Just looking at my code (which does work - I have just tested it), my code isn't a get, it is actually a POST
So it has the attribute
[HttpPost]
and in my cshtml I just use a normal form tag helper (because I submit some parameters for my pdf)
so simplified my page is
<form asp-controller="Controller" asp-action="GenerateAction">
<div class="form-group">
<input type="submit" value="Generate" class="btn btn-primary col-md-offset-2" />
</div>
</form>
Not sure how it would work in angular.
Thinking out loud, try make it a POST action. Then where you call it in your code use a $.ajax of type POST.
If I've got it right, the GET $.ajax will return the result into the data variable of the succeed function. Which I don't think is where you want it
ill try later..
I actually will be sending the report as an attachment in email as the original post says if I use it so that will be what matters.. I can't send emails in the dev env so I cant really test it.. But good to know you are here writing similiar code so I may reply here later depdning on if the boss want to use reporting or just a grid with export button.
@Chris
We had tried returning it as a FileContentResult/File before, however, for some reason, a few of the bytes were getting lost in the response from the server, and the PDF document was ending up blank. For that reason, we decided to make the example convert the bytes to Base64 ensuring that nothing is lost during the data transfer.
@Matt
Regarding the $.ajax point, it is not necessarily required to use jquery for this. I recently had to implement it without it and could do so with the Axios library and am sure that it can also be done with the fetch API or a good old XMLHttpRequest. Here's the example with axios:
const baseURL = "http://localhost:59655";
const base64ToArrayBuffer = (data) => {
var binaryString = window.atob(data);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
};
const exportToPdf = (e) => {
axios.get(baseURL + '/api/exporting/getpdf')
.then(function (response) {
if (response.data) {
const buffer = base64ToArrayBuffer(response.data)
var file = new Blob([buffer], { type: "application/pdf" })
var link = document.createElement('a')
link.href = window.URL.createObjectURL(file)
link.download = "Report.pdf";
document.body.appendChild(link)
link.click()
}
})
.catch(function (error) {
// handle error
console.log(error);
});
}
Hope this will help!
var report = new Telerik.Reporting.Report { DocumentName = rptName }; var instanceReportSource = new InstanceReportSource { ReportDocument = report };
Think your problem is in these 2 lines. If I understand it correctly, the first line is creating a blank report and giving that name. The name you give it has no meaning on what file is opened. In fact you are not opening a file, but just creating a new report in memory.
You need to use Telerik.Reporting.UriReportSource
I will give you a couple of the key lines from my code as I actually have pretty much your scenario already
var uriReportSource = new Telerik.Reporting.UriReportSource(); // Specifying an URL or a file path uriReportSource.Uri = reportsPath + "/Storage.trdp"; uriReportSource.Parameters.Clear(); uriReportSource.Parameters.Add("CustomerId", cust.Id); var result = processor.RenderReport("PDF", uriReportSource, deviceInfo); MemoryStream memStream = new MemoryStream(result.DocumentBytes); System.Net.Mail.Attachment attachment = new System.Net.Mail.Attachment(memStream, "Storage.pdf");