In the first part of the article, we created an ASP.Net Core application in which we implemented the following methods: displaying a report, displaying a report designer and saving the report changed in the designer to a server. But these are just the two features that we have stated. We need to implement the method of exporting the desired report in pdf or html format, followed by downloading this report. To let the user know which reports are available for download, we will implement a method for obtaining a list of reports.
Add the data structure for the report list to the model (Model folder) of the data:
1 2 3 4 5 6 7 |
public class Reports { // Report ID public int Id { get; set; } // Report File Name public string ReportName { get; set; } } |
Now we can create a list of reports with identifiers in our controller:
As mentioned above, we need a list of reports in the client application. It is useful for displaying a report, for editing a report in the designer and for downloading a report in pdf or html format.
1 2 3 4 5 6 |
// Get a list of reports in json format [HttpGet] public IEnumerable<Reports> Get() { return reportItems; // Gets a list of reports } |
Everything is simple here - a list of reports in json format. And now we are implementing a rather complicated method of obtaining report export:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
// Get the report file in pdf / html // Attribute has a required id parameter [HttpGet("{id}")] public IActionResult Get(int id, [FromQuery] ReportQuery query) { string mime = "application/" + query.Format; // MIME header with default value // Find the report Reports reportItem = reportItems.FirstOrDefault((p) => p.Id == id); // Get the value of the collection by identifier if (reportItem != null) { string reportPath = (webRoot + "/App_Data/" + reportItem.ReportName); // Determine the path to the report string dataPath = (webRoot + "/App_Data/nwind.xml");// Determine the path to the database using (MemoryStream stream = new MemoryStream()) // Create a stream for the report { try { using (DataSet dataSet = new DataSet()) { // Fill the source with data dataSet.ReadXml(dataPath); // Turn on FastReport web mode Config.WebMode = true; using (Report report = new Report()) { report.Load(reportPath); // Download report report.RegisterData(dataSet, "NorthWind"); // We register data in the report if (query.Parameter != null) { report.SetParameterValue("Parameter", query.Parameter); // Set the value of the report parameter, if the parameter value is transmitted in the URL } report.Prepare();//prepare a report // if pdf format is selected if (query.Format == "pdf") { // Export report to PDF PDFExport pdf = new PDFExport(); // We use a stream to store the report so as not to create extra files report.Export(pdf, stream); } // if html report format is selected else if (query.Format == "html") { // Export report to HTML HTMLExport html = new HTMLExport(); html.SinglePage = true; // Single page report html.Navigator = false; // Top navigation bar html.EmbedPictures = true; // Embeds images in a document report.Export(html, stream); mime = "text/" + query.Format; // Redefine mime for html } } } // Get the name of the resulting report file with the desired extension var file = String.Concat(Path.GetFileNameWithoutExtension(reportPath), ".", query.Format); // Download the report file return File(stream.ToArray(), mime, file); } // Handle exceptions catch { return new NoContentResult(); } finally { stream.Dispose(); } } } else return NotFound(); } |
This method receives two input parameters: id and query. The first is the report identifier from our list, and the second one is the set of report parameters that we specify in the url. We will have a look at this set below, but for now, let's continue with the Get method.
The SetParameterValue method sets the value of the parameter that we pass to the url, if necessary. This is just a demonstration of possibilities.
As you can see, from the format parameter we find out what the user selected. In our case, it can be pdf or html. Depending on the format, the report is exported. Each type of export has its own settings. As a result, the export is saved to the stream, and then is converted to a file for downloading.
Now back to the second parameter of the Get - query method. It has a type of ReportQuery. Create this class in the data model:
1 2 3 4 5 6 7 8 |
// Report Request Structure public class ReportQuery { // Format of resulting report: pdf, html public string Format { get; set; } // Value of "Parameter" variable in report public string Parameter { get; set; } } |
As you understand, Get methods are taken from WebAPI. This project is a hybrid; it has both a View part and a WebAPI interface.
Thus, in order to get a view that displays a report, you must form a url of the form:
https://localhost:44346/api/reports/ShowReport?name=ReportName.frx
In order to get a presentation with the report designer, the link needs to differ only in the name of the method:
https://localhost:44346/api/reports/Designer?name=ReportName.frx
But to get the name of the report, you need a list of available reports in the client application. You can get the list of reports in json format using url:
https://localhost:44346/api/reports/
To download the report in the selected format, you will need to form a url of the form:
https://localhost:44346/api/reports/1?format=pdf
Where the report number corresponds to the id from the list of reports on the server, and the format may have values: pdf or html. In addition, you can specify a report parameter, if there is any in your report template. Then the url will look like this:
https://localhost:44346/api/reports/1?format=pdf¶meter=REPORT
In this case, the parameter itself in the report should be called Parameter, and its value is taken from url. By analogy, you can think of as many parameters as you like in the url.
We have finished working with the server side. In the next part of the article, we will look at the way to use all this in a client application in PHP.