如何在ASP.NET Web API中使用FastReport.Net
Web API使你可以快速轻松地创建HTTP服务。与常规的ASP.Net MVC项目不同,Web API不适用于视图。要使用一种特殊类型的控制器,即返回模型对象的方法。
这种控制器的任务是传输数据,而不是表示。我们来看看如何创建一个提供FastReport报表的简单Web服务。
一、首先,我们将创建并显示两个报表。
简单的列表报表模板如下所示:
请注意,报表标题具有[Parameter]参数。你需要添加具有该名称的报表参数。此报表的数据可以从演示数据库nwind.xml的Employee表中获取,具体位置 - C: \ Program Files (x86) \ FastReports \ FastReport.Net \ Demos \ Reports。
第二个报表模板将不包含数据。你可以从文件夹C:\ Program Files(x86)\ FastReports \ FastReport.Net \ Demos \ Reports中获取现成的模板Barcodes.frx。
如上所述,我们将在我们的项目中使用两个报表和一个数据库。将它们添加到文件夹App_Data。在解决方案的浏览器中右键单击该文件夹。选择”添加” - >”现有项目”。像这样,我们添加三个文件:Barcode.frx、Simple List.frx、nwind.xml。或者,你可以简单地用鼠标将这些文件拖动到App_Data文件夹。
二、创建一个ASP.NET应用程序:
单击确定,然后转到项目类型选择:
选择空模板。在底部标记MVC和Web API选项。如果你选择一个Web API模板,你将收到一个充满演示数据的项目。
三、在引用中添加一个链接到FastReport.dll库。
四、现在,你需要添加一个数据模型。
为此,请在解决方案浏览器中选择“模型”文件夹并右键单击。在上下文菜单中,选择Add-> Class:
将该类命名为Reports.cs。默认的类类型是“Class”。点击“添加”。
在创建的类中,使用get
和set
方法添加两个变量:
namespace FastReportWebApiDemo.Models { public class Reports { // Report ID public int Id { get; set; } // Report File Name public string ReportName { get; set; } } }
五、现在将控制器添加到项目中。
在Controllers文件夹上单击右键。从上下文菜单中选择Add-> Controller。
选择控制器模板 - Web API2 Controller - Empty:
命名为ReportsController:
我们继续编码控制器中的逻辑。其任务是在浏览器中提供下载或以其中一种导出格式显示报表:PDF、HTML、png。
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 { // The class of parameters in the query 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 reports list public IEnumerable<Reports> GetAllReports() { return reportItems; } // Get report on 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 data source dataSet.ReadXml(dataPath); //Enable web mode Config.WebMode = true; using (Report report = new Report()) { report.Load(reportPath); //Load report report.RegisterData(dataSet, "NorthWind"); //Register Data in report if (query.Parameter != null) { report.SetParameterValue("Parameter", query.Parameter); // Set the value of the parameter in the report. The value 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 in PDF PDFExport pdf = new PDFExport(); // We use the flow to store the report, so as not to produce files report.Export(pdf, stream); } else if (query.Format == "html") { // Export in HTML HTMLExport html = new HTMLExport(); html.SinglePage = true; html.Navigator = false; html.EmbedPictures = true; report.Export(html, stream); } else { // Export in picture ImageExport img = new ImageExport(); img.ImageFormat = ImageExportFormat.Png; img.SeparateFiles = false; img.ResolutionX = 96; img.ResolutionY = 96; report.Export(img, stream); query.Format = "png"; } } } // Create result 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") { // Specify the file extension depending on the type of export FileName = String.Concat(Path.GetFileNameWithoutExtension(reportPath), ".", query.Format) }; // Determine the type of content for the browser result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/" + query.Format); return result; } // We handle exceptions catch { return new HttpResponseMessage(HttpStatusCode.InternalServerError); } } else return new HttpResponseMessage(HttpStatusCode.NotFound); } } }
如你所见,我们增加了另一个类到控制器。ReportQuery类定义了HTTP请求参数。这是格式,参数和内联。第一个决定报表导出的格式,第二个决定报表中的参数值,第三个决定报表是否直接在浏览器中打开。
在ReportsController类中,我们创建了一个报表数组和两个方法。名称和报表标识符在数组中定义。第一个方法 GetAllReports ()
返回可用报表的列表。在我们的案例中,有两个报表。第二种方法 GetReportById (int id, [FromUri] ReportQuery query)
返回标识符的报表。从查询属性中,我们可以得到参数格式、内联和参数。它们分别定义:报表的导出格式、报表是否会直接在浏览器中打开,要发送到报表的参数的值。
六、在报表中添加一个网页。
有了它,我们将用必要的参数向服务器发送请求。为此,请右键单击项目名称。选择Add-> HTML Page:
设置名称 - Index:
我们将下面的代码添加到页面中:
<!DOCTYPE html> <html> <head> <title>FastReport.Net Web Api Demo</title> <meta charset="utf-8" /> </head> <body> <h1>FastReport.Net Web Api Demo</h1> <hr /> <a href="/api/reports/">List Of All Reports</a><br /> <a href="/api/reports/1">Get First Report</a><br /> <a href="/api/reports/2">Get Second Report</a><br /> <a href="/api/reports/1?format=pdf">Get First Report in PDF</a><br /> <a href="/api/reports/2?format=html">Get Second Report in HTML</a><br /> <a href="/api/reports/1?format=pdf&inline=true">Get First Report in PDF inline</a><br /> <a href="/api/reports/2?format=html&inline=true">Get Second Report in HTML inline</a><br /> <a href="/api/reports/1?format=pdf&inline=true¶meter=REPORT">Get First Report in PDF inline with Parameter=REPORT</a><br /> <a href="/api/reports/1?format=html&inline=true¶meter=REPORT">Get First Report in HTML inline with Parameter=REPORT</a><br /> </body> </html>
从标题可以看出,我们可以:
- 获取报表列表;
- 获得第一份报表。根据我们在控制器中的代码,如果我们没有明确地传递格式参数,报表将以png格式显示;
- 接收第二份报表;
- 以PDF格式获取第一份报表;
- 以HTML格式获取第二份报表;
- 以PDF格式获取第一份报表并将其显示在浏览器中;
- 以HTML格式获取第二份报表并将其显示在浏览器中;
- 以PDF格式获取第一份报表并将其显示在浏览器中,并将其转移到报表中;
- 以HTML格式获取第二个报表并将其显示在浏览器中,并将其发送到报表。
七、从文件夹App_Start打开文件WebApiConfig.cs。为Index页面添加一个MapHttpRoute:
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 } ); }
在同一个文件夹中,找到RouteConfig.cs文件。它可能被删除。
八、最后一步。打开文件Global.asax。删除该行:
RouteConfig.RegisterRoutes(RouteTable.Routes);
现在路由只能通过WebApiConfig来完成。
九、运行应用程序。在浏览器中,我们看到命令列表:
- 第一个链接以XML文档的形式打开报表列表:
- 第二和第三个链接将意味着以png格式下载第一个和第二个报表;
- 第四个链接意味着以PDF格式下载第一个报表;
- 第五个链接意味着以HTML格式下载第二个报表;
- 第六个链接直接在浏览器中打开PDF格式的第一个报表:
- 第七个链接直接在浏览器中以HTML格式打开第二个报表:
- 第八个链接在浏览器中打开PDF格式的第一个报表,并发送REPORT参数:
- 第九个链接在浏览器中以HTML格式打开第一个报表并发送REPORT参数;
以上。在WebAPI中使用FastReport并不比普通的ASP.Net MVC项目更困难。
推荐阅读
- FastReport VCL报表控件开发者手册
- FastReport Online Designer中文手册
- Fastreport.Net用户手册
- FastReport.Net教程2017(持续更新中···)
- FastReport Online Designer教程2017(持续更新中···)
- Web报表系列教程(持续更新中···)
- FastReport.Net v2018.1版本更新已经发布!