How to get a report from FastReport WebApi using ajax

2017-08-23

In the article "How to use FastReport.Net in the ASP.NET Web API" we have already discussed how to create a web service for generating reports. Then we received reports on the link, now we'll look at how to get the report and display it using ajax script.

Let me remind you that our service can return a report in one of the export formats: PDF, HTML, png. We will receive the report in HTML format and display it on the web page using the ajax script.

Consider the process of creating a WebApi application from scratch. Create an ASP.Net application. WebApi. Select the Empty template and mark the options: MVC and WebApi.

The project references add FastReport.dll library.

Let's move on to creating a data model. Now the Model folder is empty. Right click on it and select Add, Class.

Call it Reports.cs. Add two fields: Id and ReportName:

1
2
3
4
5
6
7
8
9
10
namespace FastReportWebApiDemo.Models
{
 public class Reports
 {
 // Report ID
 public int Id { get; set; }
 // Report File Name
 public string ReportName { get; set; }
 }
}

You need to put report templates and a database file into the App_Data folder. In our case, these are two reports: "Simple List.frx" and "Barcode.frx";

Now, in the Controllers folder, add the controller ReportsController. It will have all the logic of the application. We do this using the context menu for the Controllers folder. Select Add -> Controller:

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using FastReport;
using FastReport.Export.Image;
using FastReport.Export.Html;
using FastReport.Export.Pdf;
using FastReport.Utils;
using FastReportWebApiDemo.Models;
using System.Web.Hosting;
using System.Data;
using System.IO;
using System.Net.Http.Headers;
 
namespace FastReportWebApiDemo.Controllers
{
// Transfer class with parameters for requesting a report
 public class ReportQuery
 {
 // Format of resulting report: png, pdf, html
 public string Format { get; set; }
 // Value of "Parameter" variable in report
 public string Parameter { get; set; }
 // Enable Inline preview in browser (generates "inline" or "attachment")
 public bool Inline { get; set; }
 }
 
 public class ReportsController : ApiController
 { //Reports list
 Reports[] reportItems = new Reports[]
 {
 new Reports { Id = 1, ReportName = "Simple List.frx" },
 new Reports { Id = 2, ReportName = "Barcode.frx" }
 };
 
 // Get list of reports
 public IEnumerable<Reports> GetAllReports()
 {
 return reportItems;
 }
 
 // Get report by ID from request
 public HttpResponseMessage GetReportById(int id, [FromUri] ReportQuery query)
 {
 // Find report
 Reports reportItem = reportItems.FirstOrDefault((p) => p.Id == id);
 if (reportItem != null)
 {
 string reportPath = HostingEnvironment.MapPath("~/App_Data/" + reportItem.ReportName);
 string dataPath = HostingEnvironment.MapPath("~/App_Data/nwind-employees.xml");
 MemoryStream stream = new MemoryStream();
 try
 {
 using (DataSet dataSet = new DataSet())
 {
// Fill the data source with the data
 dataSet.ReadXml(dataPath);
// Enable FastReport web mode
 Config.WebMode = true;
 using (Report report = new Report())
 {
 report.Load(reportPath); // Load the report
 report.RegisterData(dataSet, "NorthWind"); // Register the data in the report
 if (query.Parameter != null)
 {
 report.SetParameterValue("Parameter", query.Parameter); // Set the value of the parameter in the report. The very meaning we take from the URL
 }
 
 // Two phases of preparation to exclude the display of any dialogs
 report.PreparePhase1();
 report.PreparePhase2();
 
 if (query.Format == "pdf")
 {
// Export the report to PDF
 PDFExport pdf = new PDFExport();
// We use the stream to store the report so that we do not produce files
 report.Export(pdf, stream);
 }
 else if (query.Format == "html")
 {
// Export the report to HTML
 HTMLExport html = new HTMLExport();
 html.SinglePage = true;
 html.Navigator = false;
 html.EmbedPictures = true;
 report.Export(html, stream);
 }
 else if (query.Format == "png")
 {
// Export the report to PNG
 using (ImageExport img = new ImageExport())
 {
 img.ImageFormat = ImageExportFormat.Png;
 img.SeparateFiles = false;
 img.ResolutionX = 96;
 img.ResolutionY = 96;
 report.Export(img, stream);
 query.Format = "png";
 }
 }
 else
 {
 WebReport webReport = new WebReport();// Create a report object
 webReport.Report.Load(reportPath); // Load the report
 webReport.Report.RegisterData(dataSet, "NorthWind"); // Register the data source in the report
 if (query.Parameter != null)
 {
 webReport.Report.SetParameterValue("Parameter", query.Parameter); // Set the value of the report parameter
 }
 // inline registration of FastReport javascript
 webReport.InlineRegistration = true; // Allows you to register scripts and styles in the body of the html-page instead of placing them in the title
 webReport.Width = Unit.Percentage(100);
 webReport.Height = Unit.Percentage(100);
 // get control
 HtmlString reportHtml = webReport.GetHtml(); // load the report into HTML
 byte[] streamArray = Encoding.UTF8.GetBytes(reportHtml.ToString());
 stream.Write(streamArray, 0, streamArray.Length); // Write the report to the stream
 } 
}
 }
// create the resulting variable
 HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK)
 {
 Content = new ByteArrayContent(stream.ToArray())
 };
 
 stream.Dispose();
 
 result.Content.Headers.ContentDisposition =
 new System.Net.Http.Headers.ContentDispositionHeaderValue(query.Inline ? "inline" : "attachment")
 {
// Set the file extension depending on the type of export
 FileName = String.Concat(Path.GetFileNameWithoutExtension(reportPath), ".", query.Format)
 };
// Define the content type for the browser
result.Content.Headers.ContentType =
 new MediaTypeHeaderValue("application/" + query.Format);
 return result;
 }
// Handle Exceptions
 catch
 {
 return new HttpResponseMessage(HttpStatusCode.InternalServerError);
 }
 }
 else
 return new HttpResponseMessage(HttpStatusCode.NotFound);
 }
 }
}

In the ReportsController class, we created an array of reports and two methods. We defined the names and identifiers of the reports in the array. The GetAllReports () method returns a list of available reports. The second method, GetReportById (int id, [FromUri] ReportQuery query) returns a report by the identifier. From the query attribute, we can get the parameters format, inline, and parameter. They determine: the export format of the report, whether the report will be opened directly in the browser, the value of the parameter that is passed to the report. Particularly interesting is the method webReport.GetHtml (), which allows you to get the HTML view of the report. This is what we use to display on the page using ajax.

 In the Web.config file, you need to add two handlers:

1
2
3
4
5
6
<handlers>

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
 <add name="FastReportHandler" path="FastReport.Export.axd" verb="*" type="FastReport.Web.Handlers.WebExport" />

</handlers>

Now add the web page. Do the right click on the project and select Add-> HTML Page.

Traditionally we call the start page Index. We add the following code to the page:

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
<!DOCTYPE html>
<html>
<head>
 <title></title>
 <meta charset="utf-8" />
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
</head>
<body>
 <script type="text/javascript" language="javascript">
 function call() {
 var msg = $('#formx').serialize();
 $.ajax({ 
 type: 'GET',// Type
 url: 'http://localhost:58005/api/reports/1', // We receive a file from Rest service
 cache: false,// Caching
 timeout: 30000,// Timeout
 data: msg,
 success: function (data) {// The function will work if the data is successfully received
 $('#results').html(data);// We display the data in the form },
 beforeSend: function (data) {// The function is activated during the waiting period of data
 $('#results').html('<p> Waiting for data...</p>');
 },
 dataType: "html", // Data type 
 error: function (data) {// Function will work if an error occurs
 $('#results').html('<p> Failed to load report</p>');
 }
 });
 }
 </script>
<form method="GET" id="formx" action="javascript:void(null);" onsubmit="call()">
 <input value="Загрузить" type="submit">
 </form>
 <div id="results" typeof="submit"></div><!-- Here the result will be displayed-->
</body>
</html>

As you can see from the code, we just load the HTML report file by requesting it from the service link.

Open the file WebApiConfig.cs from the folder App_Start. Add one more MapHttpRoute for the Index page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void Register(HttpConfiguration config)
 {
 // Web API configuration and services
 // Web API routes
 config.MapHttpAttributeRoutes();
 config.Routes.MapHttpRoute(
 name: "Index",
 routeTemplate: "{id}.html",
 defaults: new { id = "index" }
 );
 
 config.Routes.MapHttpRoute(
 name: "DefaultApi",
 routeTemplate: "api/{controller}/{id}",
 defaults: new { id = RouteParameter.Optional }
 );
 }

In the same folder, the RouteConfig.cs file is located. It can be deleted.

Open the file Global.asax. Delete the line:

1
RouteConfig.RegisterRoutes(RouteTable.Routes); 

Now routing will be carried out only through WebApiConfig.

Launch the application and click the "Download" button:

 

We receive our report.

From the example considered, it is clear that working with web service for reports using Ajax is very simple.

November 20, 2024

Localization and Language Switching in FastReport VCL

FastReport VCL supports 40 languages for interface localization and allows you to change the language on the fly through menus or code, without recompilation.
November 01, 2024

New Features of the FastReport VCL Editor

We are considering new features of the report editor: extension lines, highlighting of intersecting objects, updated report and data trees.
October 30, 2024

Using Styles When Creating Reports in FastReport VCL

The article discusses one of the new features of FastReport VCL — the use of styles and style sheets.
Fast Reports
  • 800-985-8986 (English, US)
  • +4930568373928 (German)
  • +55 19 98147-8148 (Portuguese)
  • info@fast-report.com
  • 66 Canal Center Plaza, Ste 505, Alexandria, VA 22314

© 1998-2024 Fast Reports Inc.